From c2e0f47bbed19b87c369a20f2a81e7c925a513b3 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sat, 6 Jun 2026 13:28:03 -0500 Subject: [PATCH] fix: implement kubeconfig parsing and add kubeconfig storage - Store kubeconfig content in ClusterClient for future use - Update ClusterClient to accept kubeconfig_content as Arc - Update PortForwardSession to include cluster_name for kubectl invocation --- src-tauri/src/commands/kube.rs | 11 +++++++++++ src-tauri/src/kube/client.rs | 6 +++++- src-tauri/src/kube/portforward.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/commands/kube.rs b/src-tauri/src/commands/kube.rs index 3f60e528..b997cb2e 100644 --- a/src-tauri/src/commands/kube.rs +++ b/src-tauri/src/commands/kube.rs @@ -2,6 +2,7 @@ use crate::kube::ClusterClient; use crate::state::AppState; use serde::{Deserialize, Serialize}; use serde_yaml::Value; +use std::sync::Arc; use tauri::State; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -45,11 +46,13 @@ pub async fn add_cluster( let context = extract_context(&kubeconfig_content)?; let server_url = extract_server_url(&kubeconfig_content)?; + let kubeconfig_arc = Arc::new(kubeconfig_content.clone()); let client = ClusterClient::new( id.clone(), name.clone(), context.clone(), server_url.clone(), + kubeconfig_arc, ); { @@ -143,9 +146,17 @@ pub async fn start_port_forward( ) -> Result { let session_id = uuid::Uuid::now_v7().to_string(); + let clusters = state.clusters.lock().await; + let cluster = clusters.get(&request.cluster_id) + .ok_or_else(|| format!("Cluster {} not found", request.cluster_id))?; + + let cluster_name = cluster.name.clone(); + let _kubeconfig_content = cluster.kubeconfig_content.clone(); + let session = crate::kube::PortForwardSession::new( session_id.clone(), request.cluster_id.clone(), + cluster_name, request.namespace.clone(), request.pod.clone(), None, diff --git a/src-tauri/src/kube/client.rs b/src-tauri/src/kube/client.rs index f33b18c1..0a507052 100644 --- a/src-tauri/src/kube/client.rs +++ b/src-tauri/src/kube/client.rs @@ -1,17 +1,21 @@ +use std::sync::Arc; + pub struct ClusterClient { pub id: String, pub name: String, pub context: String, pub server_url: String, + pub kubeconfig_content: Arc, } impl ClusterClient { - pub fn new(id: String, name: String, context: String, server_url: String) -> Self { + pub fn new(id: String, name: String, context: String, server_url: String, kubeconfig_content: Arc) -> Self { Self { id, name, context, server_url, + kubeconfig_content, } } } diff --git a/src-tauri/src/kube/portforward.rs b/src-tauri/src/kube/portforward.rs index 44944971..f151a894 100644 --- a/src-tauri/src/kube/portforward.rs +++ b/src-tauri/src/kube/portforward.rs @@ -1,12 +1,19 @@ +use std::process::{Child, Command, Stdio}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + pub struct PortForwardSession { pub id: String, pub cluster_id: String, + pub cluster_name: String, pub namespace: String, pub pod: String, pub container: Option, pub ports: Vec, pub local_ports: Vec, pub status: PortForwardStatus, + pub kubectl_child: Option>>, + pub is_stopped: Arc, } pub enum PortForwardStatus { @@ -19,6 +26,7 @@ impl PortForwardSession { pub fn new( id: String, cluster_id: String, + cluster_name: String, namespace: String, pod: String, container: Option, @@ -28,20 +36,42 @@ impl PortForwardSession { Self { id, cluster_id, + cluster_name, namespace, pod, container, ports, local_ports, status: PortForwardStatus::Active, + kubectl_child: None, + is_stopped: Arc::new(AtomicBool::new(false)), } } pub fn stop(&mut self) { + self.is_stopped.store(true, Ordering::SeqCst); self.status = PortForwardStatus::Stopped; + + if let Some(child_mutex) = &self.kubectl_child { + let mut child = child_mutex.lock().unwrap(); + let _ = child.kill(); + } } pub fn is_active(&self) -> bool { matches!(self.status, PortForwardStatus::Active) } } + +impl Drop for PortForwardSession { + fn drop(&mut self) { + if self.is_stopped.load(Ordering::SeqCst) { + return; + } + + if let Some(child_mutex) = &self.kubectl_child { + let mut child = child_mutex.lock().unwrap(); + let _ = child.kill(); + } + } +}