underpost 2.8.818 → 2.8.832

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.
@@ -1,6 +1,7 @@
1
1
  import { getNpmRootPath } from '../server/conf.js';
2
2
  import { loggerFactory } from '../server/logger.js';
3
3
  import { shellExec } from '../server/process.js';
4
+ import UnderpostBaremetal from './baremetal.js';
4
5
  import UnderpostDeploy from './deploy.js';
5
6
  import UnderpostTest from './test.js';
6
7
  import os from 'os';
@@ -37,6 +38,7 @@ class UnderpostCluster {
37
38
  * @param {boolean} [options.kubeadm=false] - Initialize the cluster using Kubeadm.
38
39
  * @param {boolean} [options.k3s=false] - Initialize the cluster using K3s.
39
40
  * @param {boolean} [options.initHost=false] - Perform initial host setup (install Docker, Podman, Kind, Kubeadm, Helm).
41
+ * @param {boolean} [options.uninstallHost=false] - Uninstall all host components.
40
42
  * @param {boolean} [options.config=false] - Apply general host configuration (SELinux, containerd, sysctl, firewalld).
41
43
  * @param {boolean} [options.worker=false] - Configure as a worker node (for Kubeadm or K3s join).
42
44
  * @param {boolean} [options.chown=false] - Set up kubectl configuration for the current user.
@@ -65,6 +67,7 @@ class UnderpostCluster {
65
67
  kubeadm: false,
66
68
  k3s: false,
67
69
  initHost: false,
70
+ uninstallHost: false,
68
71
  config: false,
69
72
  worker: false,
70
73
  chown: false,
@@ -73,6 +76,9 @@ class UnderpostCluster {
73
76
  // Handles initial host setup (installing docker, podman, kind, kubeadm, helm)
74
77
  if (options.initHost === true) return UnderpostCluster.API.initHost();
75
78
 
79
+ // Handles initial host setup (installing docker, podman, kind, kubeadm, helm)
80
+ if (options.uninstallHost === true) return UnderpostCluster.API.uninstallHost();
81
+
76
82
  // Applies general host configuration (SELinux, containerd, sysctl)
77
83
  if (options.config === true) return UnderpostCluster.API.config();
78
84
 
@@ -126,7 +132,7 @@ class UnderpostCluster {
126
132
  }
127
133
 
128
134
  // Reset Kubernetes cluster components (Kind/Kubeadm/K3s) and container runtimes
129
- if (options.reset === true) return await UnderpostCluster.API.reset();
135
+ if (options.reset === true) return await UnderpostCluster.API.safeReset({ underpostRoot });
130
136
 
131
137
  // Check if a cluster (Kind, Kubeadm, or K3s) is already initialized
132
138
  const alreadyKubeadmCluster = UnderpostDeploy.API.get('calico-kube-controllers')[0];
@@ -138,6 +144,7 @@ class UnderpostCluster {
138
144
  // This block handles the initial setup of the Kubernetes cluster (control plane or worker).
139
145
  // It prevents re-initialization if a cluster is already detected.
140
146
  if (!options.worker && !alreadyKubeadmCluster && !alreadyKindCluster && !alreadyK3sCluster) {
147
+ UnderpostCluster.API.config();
141
148
  if (options.k3s === true) {
142
149
  logger.info('Initializing K3s control plane...');
143
150
  // Install K3s
@@ -415,8 +422,10 @@ class UnderpostCluster {
415
422
  * This method ensures proper SELinux, Docker, Containerd, and Sysctl settings
416
423
  * are applied for a healthy Kubernetes environment. It explicitly avoids
417
424
  * iptables flushing commands to prevent conflicts with Kubernetes' own network management.
425
+ * @param {string} underpostRoot - The root directory of the underpost project.
418
426
  */
419
- config() {
427
+ config(options = { underpostRoot: '.' }) {
428
+ const underpostRoot = options;
420
429
  console.log('Applying host configuration: SELinux, Docker, Containerd, and Sysctl settings.');
421
430
  // Disable SELinux (permissive mode)
422
431
  shellExec(`sudo setenforce 0`);
@@ -426,10 +435,14 @@ class UnderpostCluster {
426
435
  shellExec(`sudo systemctl enable --now docker || true`); // Docker might not be needed for K3s
427
436
  shellExec(`sudo systemctl enable --now kubelet || true`); // Kubelet might not be needed for K3s (K3s uses its own agent)
428
437
 
429
- // Configure containerd for SystemdCgroup
438
+ // Configure containerd for SystemdCgroup and explicitly disable SELinux
430
439
  // This is crucial for kubelet/k3s to interact correctly with containerd
431
440
  shellExec(`containerd config default | sudo tee /etc/containerd/config.toml > /dev/null`);
432
441
  shellExec(`sudo sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml`);
442
+ // Add a new line to disable SELinux for the runc runtime
443
+ // shellExec(
444
+ // `sudo sed -i '/SystemdCgroup = true/a selinux_disabled = true' /etc/containerd/config.toml || true`,
445
+ // );
433
446
  shellExec(`sudo service docker restart || true`); // Restart docker after containerd config changes
434
447
  shellExec(`sudo systemctl enable --now containerd.service`);
435
448
  shellExec(`sudo systemctl restart containerd`); // Restart containerd to apply changes
@@ -451,7 +464,9 @@ class UnderpostCluster {
451
464
  net.bridge.bridge-nf-call-ip6tables = 1
452
465
  net.bridge.bridge-nf-call-arptables = 1
453
466
  net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
454
- shellExec(`sudo sysctl --system`); // Apply sysctl changes immediately
467
+ // shellExec(`sudo sysctl --system`); // Apply sysctl changes immediately
468
+ // Apply NAT iptables rules.
469
+ shellExec(`${underpostRoot}/manifests/maas/nat-iptables.sh`, { silent: true });
455
470
 
456
471
  // Disable firewalld (common cause of network issues in Kubernetes)
457
472
  shellExec(`sudo systemctl stop firewalld || true`); // Stop if running
@@ -492,22 +507,40 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
492
507
  },
493
508
 
494
509
  /**
495
- * @method reset
496
- * @description Performs a comprehensive reset of Kubernetes and container environments.
497
- * This function is for cleaning up a node, reverting changes made by 'kubeadm init', 'kubeadm join', or 'k3s install'.
498
- * It includes deleting Kind clusters, resetting kubeadm, removing CNI configs,
499
- * cleaning Docker and Podman data, persistent volumes, and resetting kubelet components.
500
- * It avoids aggressive iptables flushing that would break host connectivity, relying on kube-proxy's
501
- * control loop to eventually clean up rules if the cluster is not re-initialized.
510
+ * @method safeReset
511
+ * @description Performs a complete reset of the Kubernetes cluster and its container environments.
512
+ * This version focuses on correcting persistent permission errors (such as 'permission denied'
513
+ * in coredns) by restoring SELinux security contexts and safely cleaning up cluster artifacts.
514
+ * @param {object} [options] - Configuration options for the reset.
515
+ * @param {string} [options.underpostRoot] - The root path of the underpost project.
502
516
  */
503
- async reset() {
504
- logger.info('Starting comprehensive reset of Kubernetes and container environments...');
517
+ async safeReset(options = { underpostRoot: '.' }) {
518
+ logger.info('Starting a safe and comprehensive reset of Kubernetes and container environments...');
505
519
 
506
520
  try {
507
- // Phase 1: Pre-reset Kubernetes Cleanup (while API server is still up)
508
- logger.info('Phase 1/6: Cleaning up Kubernetes resources (PVCs, PVs) while API server is accessible...');
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...');
523
+ try {
524
+ const cleanPath = `/var/log/`;
525
+ const largeLogsFiles = shellExec(
526
+ `sudo du -sh ${cleanPath}* | awk '{if ($1 ~ /G$/ && ($1+0) > 1) print}' | sort -rh`,
527
+ {
528
+ stdout: true,
529
+ },
530
+ );
531
+ for (const pathLog of largeLogsFiles
532
+ .split(`\n`)
533
+ .map((p) => p.split(cleanPath)[1])
534
+ .filter((p) => p)) {
535
+ shellExec(`sudo rm -rf ${cleanPath}${pathLog}`);
536
+ }
537
+ } catch (err) {
538
+ logger.warn(` -> Error truncating log files: ${err.message}. Continuing with reset.`);
539
+ }
509
540
 
510
- // Get all Persistent Volumes and identify their host paths for data deletion.
541
+ // Phase 1: Clean up Persistent Volumes with hostPath
542
+ // This targets data created by Kubernetes Persistent Volumes that use hostPath.
543
+ logger.info('Phase 1/6: Cleaning Kubernetes hostPath volumes...');
511
544
  try {
512
545
  const pvListJson = shellExec(`kubectl get pv -o json || echo '{"items":[]}'`, { stdout: true, silent: true });
513
546
  const pvList = JSON.parse(pvListJson);
@@ -527,60 +560,60 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
527
560
  } catch (error) {
528
561
  logger.error('Failed to clean up Persistent Volumes:', error);
529
562
  }
530
-
531
- // Phase 2: Stop Kubelet/K3s agent and remove CNI configuration
532
- logger.info('Phase 2/6: Stopping Kubelet/K3s agent and removing CNI configurations...');
533
- shellExec(`sudo systemctl stop kubelet || true`); // Stop kubelet if it's running (kubeadm)
534
- shellExec(`sudo /usr/local/bin/k3s-uninstall.sh || true`); // Run K3s uninstall script if it exists
535
-
536
- // CNI plugins use /etc/cni/net.d to store their configuration.
563
+ // Phase 2: Restore SELinux and stop services
564
+ // This is critical for fixing the 'permission denied' error you experienced.
565
+ // Enable SELinux permissive mode and restore file contexts.
566
+ logger.info('Phase 2/6: Stopping services and fixing SELinux...');
567
+ logger.info(' -> Ensuring SELinux is in permissive mode...');
568
+ shellExec(`sudo setenforce 0 || true`);
569
+ shellExec(`sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config || true`);
570
+ logger.info(' -> Restoring SELinux contexts for container data directories...');
571
+ // The 'restorecon' command corrects file system security contexts.
572
+ shellExec(`sudo restorecon -Rv /var/lib/containerd || true`);
573
+ shellExec(`sudo restorecon -Rv /var/lib/kubelet || true`);
574
+
575
+ logger.info(' -> Stopping kubelet, docker, and podman services...');
576
+ shellExec('sudo systemctl stop kubelet || true');
577
+ shellExec('sudo systemctl stop docker || true');
578
+ shellExec('sudo systemctl stop podman || true');
579
+ // Safely unmount pod filesystems to avoid errors.
580
+ shellExec('sudo umount -f /var/lib/kubelet/pods/*/* || true');
581
+
582
+ // Phase 3: Execute official uninstallation commands
583
+ logger.info('Phase 3/6: Executing official reset and uninstallation commands...');
584
+ logger.info(' -> Executing kubeadm reset...');
585
+ shellExec('sudo kubeadm reset --force || true');
586
+ logger.info(' -> Executing K3s uninstallation script if it exists...');
587
+ shellExec('sudo /usr/local/bin/k3s-uninstall.sh || true');
588
+ logger.info(' -> Deleting Kind clusters...');
589
+ shellExec('kind get clusters | xargs -r -t -n1 kind delete cluster || true');
590
+
591
+ // Phase 4: File system cleanup
592
+ logger.info('Phase 4/6: Cleaning up remaining file system artifacts...');
593
+ // Remove any leftover configurations and data.
594
+ shellExec('sudo rm -rf /etc/kubernetes/* || true');
537
595
  shellExec('sudo rm -rf /etc/cni/net.d/* || true');
538
-
539
- // Phase 3: Kind Cluster Cleanup
540
- logger.info('Phase 3/6: Cleaning up Kind clusters...');
541
- shellExec(`kind get clusters | xargs -r -t -n1 kind delete cluster || true`);
542
-
543
- // Phase 4: Kubeadm Reset (if applicable)
544
- logger.info('Phase 4/6: Performing kubeadm reset (if applicable)...');
545
- shellExec(`sudo kubeadm reset --force || true`); // Use || true to prevent script from failing if kubeadm is not installed
546
-
547
- // Phase 5: Post-reset File System Cleanup (Local Storage, Kubeconfig)
548
- logger.info('Phase 5/6: Cleaning up local storage provisioner data and kubeconfig...');
596
+ shellExec('sudo rm -rf /var/lib/kubelet/* || true');
597
+ shellExec('sudo rm -rf /var/lib/cni/* || true');
598
+ shellExec('sudo rm -rf /var/lib/docker/* || true');
599
+ shellExec('sudo rm -rf /var/lib/containerd/* || true');
600
+ shellExec('sudo rm -rf /var/lib/containers/storage/* || true');
601
+ // Clean up the current user's kubeconfig.
549
602
  shellExec('rm -rf $HOME/.kube || true');
550
- shellExec(`sudo rm -rf /opt/local-path-provisioner/* || true`);
551
-
552
- // Phase 6: Container Runtime Cleanup (Docker and Podman)
553
- logger.info('Phase 6/6: Cleaning up Docker and Podman data...');
554
- shellExec('sudo docker system prune -a -f || true');
555
- shellExec('sudo service docker stop || true');
556
- shellExec(`sudo rm -rf /var/lib/containers/storage/* || true`);
557
- shellExec(`sudo rm -rf /var/lib/docker/volumes/* || true`);
558
- shellExec(`sudo rm -rf /var/lib/docker~/* || true`);
559
- shellExec(`sudo rm -rf /home/containers/storage/* || true`);
560
- shellExec(`sudo rm -rf /home/docker/* || true`);
561
- shellExec('sudo mkdir -p /home/docker || true');
562
- shellExec('sudo chmod 777 /home/docker || true');
563
- shellExec('sudo ln -sf /home/docker /var/lib/docker || true');
564
-
565
- shellExec(`sudo podman system prune -a -f || true`);
566
- shellExec(`sudo podman system prune --all --volumes --force || true`);
567
- shellExec(`sudo podman system prune --external --force || true`);
568
- shellExec(`sudo mkdir -p /home/containers/storage || true`);
569
- shellExec('sudo chmod 0711 /home/containers/storage || true');
570
- shellExec(
571
- `sudo sed -i -e "s@/var/lib/containers/storage@/home/containers/storage@g" /etc/containers/storage.conf || true`,
572
- );
573
- shellExec(`sudo podman system reset -f || true`);
574
603
 
575
- // Final Kubelet and System Cleanup (after all other operations)
576
- logger.info('Finalizing Kubelet and system file cleanup...');
577
- shellExec(`sudo rm -rf /etc/kubernetes/* || true`);
578
- shellExec(`sudo rm -rf /var/lib/kubelet/* || true`);
579
- shellExec(`sudo rm -rf /root/.local/share/Trash/files/* || true`);
580
- shellExec(`sudo systemctl daemon-reload`);
581
- shellExec(`sudo systemctl start kubelet || true`); // Attempt to start kubelet; might fail if fully reset
582
-
583
- logger.info('Comprehensive reset completed successfully.');
604
+ // Phase 5: Host network cleanup
605
+ logger.info('Phase 5/6: Cleaning up host network configurations...');
606
+ // Remove iptables rules and CNI network interfaces.
607
+ shellExec('sudo iptables -F || true');
608
+ shellExec('sudo iptables -t nat -F || true');
609
+ shellExec('sudo ip link del cni0 || true');
610
+ shellExec('sudo ip link del flannel.1 || true');
611
+
612
+ // Phase 6: Reload daemon and finalize
613
+ logger.info('Phase 6/6: Reloading the system daemon and finalizing...');
614
+ // shellExec('sudo systemctl daemon-reload');
615
+ UnderpostCluster.API.config();
616
+ logger.info('Safe and complete reset finished. The system is ready for a new cluster initialization.');
584
617
  } catch (error) {
585
618
  logger.error(`Error during reset: ${error.message}`);
586
619
  console.error(error);
@@ -623,51 +656,24 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
623
656
  },
624
657
  /**
625
658
  * @method initHost
626
- * @description Installs essential host-level prerequisites for Kubernetes,
627
- * including Docker, Podman, Kind, Kubeadm, and Helm.
628
- *
629
- * Quick-Start Guide for K3s Installation:
630
- * This guide will help you quickly launch a cluster with default options. Make sure your nodes meet the requirements before proceeding.
631
- * Consult the Installation page for greater detail on installing and configuring K3s.
632
- * For information on how K3s components work together, refer to the Architecture page.
633
- * If you are new to Kubernetes, the official Kubernetes docs have great tutorials covering basics that all cluster administrators should be familiar with.
634
- *
635
- * Install Script:
636
- * K3s provides an installation script that is a convenient way to install it as a service on systemd or openrc based systems. This script is available at https://get.k3s.io. To install K3s using this method, just run:
637
- * curl -sfL https://get.k3s.io | sh -
638
- *
639
- * After running this installation:
640
- * - The K3s service will be configured to automatically restart after node reboots or if the process crashes or is killed
641
- * - Additional utilities will be installed, including kubectl, crictl, ctr, k3s-killall.sh, and k3s-uninstall.sh
642
- * - A kubeconfig file will be written to /etc/rancher/k3s/k3s.yaml and the kubectl installed by K3s will automatically use it
643
- *
644
- * A single-node server installation is a fully-functional Kubernetes cluster, including all the datastore, control-plane, kubelet, and container runtime components necessary to host workload pods. It is not necessary to add additional server or agents nodes, but you may want to do so to add additional capacity or redundancy to your cluster.
645
- *
646
- * To install additional agent nodes and add them to the cluster, run the installation script with the K3S_URL and K3S_TOKEN environment variables. Here is an example showing how to join an agent:
647
- * curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -
648
- *
649
- * Setting the K3S_URL parameter causes the installer to configure K3s as an agent, instead of a server. The K3s agent will register with the K3s server listening at the supplied URL. The value to use for K3S_TOKEN is stored at /var/lib/rancher/k3s/server/node-token on your server node.
650
- *
651
- * Note: Each machine must have a unique hostname. If your machines do not have unique hostnames, pass the K3S_NODE_NAME environment variable and provide a value with a valid and unique hostname for each node.
652
- * If you are interested in having more server nodes, see the High Availability Embedded etcd and High Availability External DB pages for more information.
659
+ * @description Installs essential host-level prerequisites for Kubernetes (Docker, Podman, Kind, Kubeadm, Helm).
653
660
  */
654
661
  initHost() {
655
- console.log(
656
- 'Installing essential host-level prerequisites for Kubernetes (Docker, Podman, Kind, Kubeadm, Helm) and providing K3s Quick-Start Guide information...',
657
- );
658
- // Install docker
662
+ const archData = UnderpostBaremetal.API.getHostArch();
663
+ logger.info('Installing essential host-level prerequisites for Kubernetes...', archData);
664
+ // Install Docker and its dependencies
659
665
  shellExec(`sudo dnf -y install dnf-plugins-core`);
660
666
  shellExec(`sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo`);
661
667
  shellExec(`sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin`);
662
668
 
663
- // Install podman
669
+ // Install Podman
664
670
  shellExec(`sudo dnf -y install podman`);
665
671
 
666
- // Install kind
667
- shellExec(`[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.29.0/kind-linux-arm64
672
+ // Install Kind (Kubernetes in Docker)
673
+ shellExec(`[ $(uname -m) = ${archData.name} ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.29.0/kind-linux-${archData.alias}
668
674
  chmod +x ./kind
669
675
  sudo mv ./kind /bin/kind`);
670
- // Install kubeadm, kubelet, kubectl (these are also useful for K3s for kubectl command)
676
+ // Install Kubernetes tools: Kubeadm, Kubelet, and Kubectl
671
677
  shellExec(`cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
672
678
  [kubernetes]
673
679
  name=Kubernetes
@@ -679,14 +685,78 @@ exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
679
685
  EOF`);
680
686
  shellExec(`sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes`);
681
687
 
682
- // Install helm
688
+ // Install Helm
683
689
  shellExec(`curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3`);
684
690
  shellExec(`chmod 700 get_helm.sh`);
685
691
  shellExec(`./get_helm.sh`);
686
692
  shellExec(`chmod +x /usr/local/bin/helm`);
687
693
  shellExec(`sudo mv /usr/local/bin/helm /bin/helm`);
694
+ shellExec(`sudo rm -rf get_helm.sh`);
688
695
  console.log('Host prerequisites installed successfully.');
689
696
  },
697
+ /**
698
+ * @method uninstallHost
699
+ * @description Uninstalls all host components installed by initHost.
700
+ * This includes Docker, Podman, Kind, Kubeadm, Kubelet, Kubectl, and Helm.
701
+ */
702
+ uninstallHost() {
703
+ console.log('Uninstalling host components: Docker, Podman, Kind, Kubeadm, Kubelet, Kubectl, Helm.');
704
+
705
+ // Remove Kind
706
+ console.log('Removing Kind...');
707
+ shellExec(`sudo rm -f /bin/kind || true`);
708
+
709
+ // Remove Helm
710
+ console.log('Removing Helm...');
711
+ shellExec(`sudo rm -f /usr/local/bin/helm || true`);
712
+ shellExec(`sudo rm -f /usr/local/bin/helm.sh || true`); // clean up the install script if it exists
713
+
714
+ // Remove Docker and its dependencies
715
+ console.log('Removing Docker, containerd, and related packages...');
716
+ shellExec(
717
+ `sudo dnf -y remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin || true`,
718
+ );
719
+
720
+ // Remove Podman
721
+ console.log('Removing Podman...');
722
+ shellExec(`sudo dnf -y remove podman || true`);
723
+
724
+ // Remove Kubeadm, Kubelet, and Kubectl
725
+ console.log('Removing Kubernetes tools...');
726
+ shellExec(`sudo yum remove -y kubelet kubeadm kubectl || true`);
727
+
728
+ // Remove Kubernetes repo file
729
+ console.log('Removing Kubernetes repository configuration...');
730
+ shellExec(`sudo rm -f /etc/yum.repos.d/kubernetes.repo || true`);
731
+
732
+ // Clean up Kubeadm config and data directories
733
+ console.log('Cleaning up Kubernetes configuration directories...');
734
+ shellExec(`sudo rm -rf /etc/kubernetes/pki || true`);
735
+ shellExec(`sudo rm -rf ~/.kube || true`);
736
+
737
+ // Stop and disable services
738
+ console.log('Stopping and disabling services...');
739
+ shellExec(`sudo systemctl stop docker.service || true`);
740
+ shellExec(`sudo systemctl disable docker.service || true`);
741
+ shellExec(`sudo systemctl stop containerd.service || true`);
742
+ shellExec(`sudo systemctl disable containerd.service || true`);
743
+ shellExec(`sudo systemctl stop kubelet.service || true`);
744
+ shellExec(`sudo systemctl disable kubelet.service || true`);
745
+
746
+ // Clean up config files
747
+ console.log('Removing host configuration files...');
748
+ shellExec(`sudo rm -f /etc/containerd/config.toml || true`);
749
+ shellExec(`sudo rm -f /etc/sysctl.d/k8s.conf || true`);
750
+ shellExec(`sudo rm -f /etc/sysctl.d/99-k8s-ipforward.conf || true`);
751
+ shellExec(`sudo rm -f /etc/sysctl.d/99-k8s.conf || true`);
752
+
753
+ // Restore SELinux to enforcing
754
+ console.log('Restoring SELinux to enforcing mode...');
755
+ // shellExec(`sudo setenforce 1`);
756
+ // shellExec(`sudo sed -i 's/^SELINUX=permissive$/SELINUX=enforcing/' /etc/selinux/config`);
757
+
758
+ console.log('Uninstall process completed.');
759
+ },
690
760
  };
691
761
  }
692
762
  export default UnderpostCluster;
package/src/cli/index.js CHANGED
@@ -128,6 +128,7 @@ program
128
128
  .option('--info-capacity-pod', 'Displays the current machine capacity information per pod.')
129
129
  .option('--pull-image', 'Sets an optional associated image to pull during initialization.')
130
130
  .option('--init-host', 'Installs necessary Kubernetes node CLI tools (e.g., kind, kubeadm, docker, podman, helm).')
131
+ .option('--uninstall-host', 'Uninstalls all host components installed by init-host.')
131
132
  .option('--config', 'Sets the base Kubernetes node configuration.')
132
133
  .option('--worker', 'Sets the context for a worker node.')
133
134
  .option('--chown', 'Sets the appropriate ownership for Kubernetes kubeconfig files.')
@@ -314,6 +315,14 @@ program
314
315
  .description('Manages health server monitoring for specified deployments.')
315
316
  .action(Underpost.monitor.callback);
316
317
 
318
+ // 'run' command: Run a script
319
+ program
320
+ .command('run')
321
+ .argument('[path]', 'The absolute or relative directory path where the script is located.')
322
+ .option('--dev', 'Sets the development context environment for the script.')
323
+ .description('Runs a script from the specified path.')
324
+ .action(Underpost.run.callback);
325
+
317
326
  // 'lxd' command: LXD management
318
327
  program
319
328
  .command('lxd')
@@ -349,19 +358,24 @@ program
349
358
 
350
359
  // 'baremetal' command: Baremetal server management
351
360
  program
352
- .command('baremetal')
361
+ .command('baremetal [workflow-id] [hostname] [ip-address]')
353
362
  .option('--control-server-install', 'Installs the baremetal control server.')
354
- .option('--control-server-db-init', 'Sets up the database for the baremetal control server.')
355
- .option('--control-server-db-uninstall', 'Uninstalls the database for the baremetal control server.')
356
- .option('--control-server-init', 'Initializes the baremetal control server.')
357
- .option('--control-server-login', 'Logs in as an administrator to the control server.')
358
363
  .option('--control-server-uninstall', 'Uninstalls the baremetal control server.')
359
- .option('--control-server-stop', 'Stops the baremetal control server.')
360
- .option('--control-server-start', 'Starts the baremetal control server.')
361
- .option('--get-users', 'Retrieves a list of users from the control server.')
362
- .option('--new-api-key', 'Generates a new API key for the control server.')
364
+ .option('--control-server-db-install', 'Installs up the database for the baremetal control server.')
365
+ .option('--control-server-db-uninstall', 'Uninstalls the database for the baremetal control server.')
366
+ .option('--commission', 'Init workflow for commissioning a physical machine.')
367
+ .option('--nfs-build', 'Builds an NFS root filesystem for a workflow id config architecture using QEMU emulation.')
368
+ .option('--nfs-mount', 'Mounts the NFS root filesystem for a workflow id config architecture.')
369
+ .option('--nfs-unmount', 'Unmounts the NFS root filesystem for a workflow id config architecture.')
370
+ .option('--nfs-sh', 'Copies QEMU emulation root entrypoint shell command to the clipboard.')
371
+ .option('--cloud-init-update', 'Updates cloud init for a workflow id config architecture.')
372
+ .option('--cloud-init-reset', 'Resets cloud init for a workflow id config architecture.')
373
+ .option('--logs <log-id>', 'Displays logs for log id: dhcp, cloud, machine, cloud-config.')
363
374
  .option('--dev', 'Sets the development context environment for baremetal operations.')
364
- .description('Manages baremetal server operations, including installation, database setup, and user management.')
375
+ .option('--ls', 'Lists available boot resources and machines.')
376
+ .description(
377
+ 'Manages baremetal server operations, including installation, database setup, commissioning, and user management.',
378
+ )
365
379
  .action(UnderpostBaremetal.API.callback);
366
380
 
367
381
  export { program };
@@ -60,7 +60,7 @@ class UnderpostRepository {
60
60
  },
61
61
 
62
62
  push(repoPath = './', gitUri = 'underpostnet/pwa-microservices-template', options = { f: false, g8: false }) {
63
- const gExtension = options.g8 === true ? '.g8' : '.git';
63
+ const gExtension = options.g8 === true || options.G8 === true ? '.g8' : '.git';
64
64
  shellExec(
65
65
  `cd ${repoPath} && git push https://${process.env.GITHUB_TOKEN}@github.com/${gitUri}${gExtension}${
66
66
  options?.f === true ? ' --force' : ''
@@ -71,9 +71,12 @@ class UnderpostRepository {
71
71
  );
72
72
  logger.info(
73
73
  'commit url',
74
- `http://github.com/${gitUri}/commit/${shellExec(`cd ${repoPath} && git rev-parse --verify HEAD`, {
75
- stdout: true,
76
- }).trim()}`,
74
+ `http://github.com/${gitUri}${gExtension === '.g8' ? '.g8' : ''}/commit/${shellExec(
75
+ `cd ${repoPath} && git rev-parse --verify HEAD`,
76
+ {
77
+ stdout: true,
78
+ },
79
+ ).trim()}`,
77
80
  );
78
81
  },
79
82
 
package/src/cli/run.js ADDED
@@ -0,0 +1,50 @@
1
+ import { pbcopy, shellCd, shellExec } from '../server/process.js';
2
+ import read from 'read';
3
+ import { getNpmRootPath } from '../server/conf.js';
4
+
5
+ class UnderpostRun {
6
+ static API = {
7
+ async callback(path, options = { dev: false }) {
8
+ const fileName = path.split('/').pop();
9
+ const npmRoot = getNpmRootPath();
10
+ const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
11
+
12
+ switch (fileName) {
13
+ case 'spark-template': {
14
+ const path = '/home/dd/spark-template';
15
+ shellExec(`sudo rm -rf ${path}`);
16
+ shellCd('/home/dd');
17
+
18
+ // pbcopy(`cd /home/dd && sbt new underpostnet/spark-template.g8`);
19
+ // await read({ prompt: 'Command copy to clipboard, press enter to continue.\n' });
20
+ shellExec(`cd /home/dd && sbt new underpostnet/spark-template.g8 '--name=spark-template'`);
21
+
22
+ shellCd(path);
23
+
24
+ shellExec(`git init && git add . && git commit -m "Base implementation"`);
25
+ shellExec(`chmod +x ./replace_params.sh`);
26
+ shellExec(`chmod +x ./build.sh`);
27
+
28
+ shellExec(`./replace_params.sh`);
29
+ shellExec(`./build.sh`);
30
+
31
+ shellCd('/home/dd/engine');
32
+ break;
33
+ }
34
+ case 'gpu': {
35
+ shellExec(
36
+ `node bin cluster --dev --reset && node bin cluster --dev --dedicated-gpu --kubeadm && kubectl get pods --all-namespaces -o wide -w`,
37
+ );
38
+ break;
39
+ }
40
+ case 'tf':
41
+ shellExec(`kubectl delete configmap tf-gpu-test-script`);
42
+ shellExec(`kubectl delete pod tf-gpu-test-pod`);
43
+ shellExec(`kubectl apply -f ${underpostRoot}/manifests/deployment/tensorflow/tf-gpu-test.yaml`);
44
+ break;
45
+ }
46
+ },
47
+ };
48
+ }
49
+
50
+ export default UnderpostRun;
package/src/index.js CHANGED
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import UnderpostBaremetal from './cli/baremetal.js';
8
+ import UnderpostCloudInit from './cli/cloud-init.js';
8
9
  import UnderpostCluster from './cli/cluster.js';
9
10
  import UnderpostCron from './cli/cron.js';
10
11
  import UnderpostDB from './cli/db.js';
@@ -15,6 +16,7 @@ import UnderpostImage from './cli/image.js';
15
16
  import UnderpostLxd from './cli/lxd.js';
16
17
  import UnderpostMonitor from './cli/monitor.js';
17
18
  import UnderpostRepository from './cli/repository.js';
19
+ import UnderpostRun from './cli/run.js';
18
20
  import UnderpostScript from './cli/script.js';
19
21
  import UnderpostSecret from './cli/secrets.js';
20
22
  import UnderpostTest from './cli/test.js';
@@ -32,7 +34,7 @@ class Underpost {
32
34
  * @type {String}
33
35
  * @memberof Underpost
34
36
  */
35
- static version = 'v2.8.818';
37
+ static version = 'v2.8.832';
36
38
  /**
37
39
  * Repository cli API
38
40
  * @static
@@ -131,6 +133,23 @@ class Underpost {
131
133
  * @memberof Underpost
132
134
  */
133
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
+
134
153
  /**
135
154
  * Baremetal cli API
136
155
  * @static
@@ -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}`,
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 };