|
1 | | -use crate::entities::{ColimaConfig, InstallationMethod, InstallationProgress}; |
| 1 | +use crate::entities::{ |
| 2 | + ColimaConfig, ColimaEngineStopProgress, InstallationMethod, InstallationProgress, |
| 3 | +}; |
2 | 4 | use crate::services::shell::{ |
3 | 5 | check_colima_status, get_docker_context_endpoints, install_packages_via_homebrew, |
4 | | - start_colima_with_config, validate_colima_startup, |
| 6 | + start_colima_with_config, stop_colima, validate_colima_startup, |
5 | 7 | }; |
6 | 8 | use bollard::Docker; |
7 | 9 | use tauri::{AppHandle, Emitter}; |
@@ -225,6 +227,109 @@ pub async fn start_colima_vm(app_handle: &AppHandle, config: ColimaConfig) -> Re |
225 | 227 | result |
226 | 228 | } |
227 | 229 |
|
| 230 | +#[instrument(skip_all, err)] |
| 231 | +pub async fn stop_colima_vm(app_handle: &AppHandle) -> Result<(), String> { |
| 232 | + debug!("Stopping Colima VM"); |
| 233 | + |
| 234 | + // Create a channel for progress updates |
| 235 | + let (tx, mut rx) = mpsc::channel::<ColimaEngineStopProgress>(100); |
| 236 | + |
| 237 | + // Clone the sender for the background task |
| 238 | + let tx_clone = tx.clone(); |
| 239 | + |
| 240 | + // Clone the app_handle for use in the background task |
| 241 | + let app_handle_clone = app_handle.clone(); |
| 242 | + let app_handle_for_events = app_handle.clone(); |
| 243 | + |
| 244 | + // Spawn the VM startup task |
| 245 | + let vm_handle = tokio::spawn(async move { |
| 246 | + let mut progress = ColimaEngineStopProgress { |
| 247 | + step: "Stopping Colima VM...".to_string(), |
| 248 | + message: "Stopping Colima virtual machine".to_string(), |
| 249 | + percentage: 10, |
| 250 | + logs: vec![], |
| 251 | + }; |
| 252 | + |
| 253 | + // Send initial progress |
| 254 | + let _ = tx_clone.send(progress.clone()).await; |
| 255 | + |
| 256 | + // Step 1: Check if Colima is already running |
| 257 | + progress.step = "Checking Colima status...".to_string(); |
| 258 | + progress.message = "Verifying current VM status".to_string(); |
| 259 | + progress.percentage = 20; |
| 260 | + progress |
| 261 | + .logs |
| 262 | + .push("[INFO] Checking Colima status".to_string()); |
| 263 | + let _ = tx_clone.send(progress.clone()).await; |
| 264 | + |
| 265 | + let status_result = check_colima_status(&app_handle_clone).await; |
| 266 | + if let Ok(true) = status_result { |
| 267 | + progress.step = "Colima VM is running".to_string(); |
| 268 | + progress.message = "Colima VM is running".to_string(); |
| 269 | + progress.percentage = 30; |
| 270 | + progress |
| 271 | + .logs |
| 272 | + .push("[INFO] Colima VM is running".to_string()); |
| 273 | + let _ = tx_clone.send(progress.clone()).await; |
| 274 | + return Ok(()); |
| 275 | + } |
| 276 | + |
| 277 | + // Step 2: Stop Colima VM |
| 278 | + progress.step = "Stopping VM...".to_string(); |
| 279 | + progress.message = "Stopping Colima virtual machine".to_string(); |
| 280 | + progress.percentage = 40; |
| 281 | + progress.logs.push("[INFO] Stopping Colima VM".to_string()); |
| 282 | + let _ = tx_clone.send(progress.clone()).await; |
| 283 | + |
| 284 | + let stop_result = stop_colima(&app_handle_clone).await; |
| 285 | + if let Err(e) = &stop_result { |
| 286 | + progress.step = "VM stop failed".to_string(); |
| 287 | + progress.message = format!("Failed to stop Colima VM: {}", e); |
| 288 | + progress.percentage = 100; |
| 289 | + progress.logs.push(format!("[ERROR] {}", e)); |
| 290 | + let _ = tx_clone.send(progress.clone()).await; |
| 291 | + return Err(e.clone()); |
| 292 | + } |
| 293 | + // Wait a bit for the VM to fully stop |
| 294 | + tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; |
| 295 | + |
| 296 | + progress.step = "VM stop complete".to_string(); |
| 297 | + progress.message = "Colima VM is stopped successfully".to_string(); |
| 298 | + progress.percentage = 100; |
| 299 | + progress |
| 300 | + .logs |
| 301 | + .push("[INFO] Colima VM stopped successfully".to_string()); |
| 302 | + let _ = tx_clone.send(progress.clone()).await; |
| 303 | + |
| 304 | + Ok(()) |
| 305 | + }); |
| 306 | + |
| 307 | + // Handle progress updates and send them to the frontend |
| 308 | + let app_handle_for_progress = app_handle.clone(); |
| 309 | + let _progress_handle = tokio::spawn(async move { |
| 310 | + while let Some(progress) = rx.recv().await { |
| 311 | + let _ = app_handle_for_progress.emit("vm-stop-progress", progress); |
| 312 | + } |
| 313 | + }); |
| 314 | + |
| 315 | + // Wait for VM stop to complete |
| 316 | + let result = vm_handle |
| 317 | + .await |
| 318 | + .map_err(|e| format!("VM stop task failed: {}", e))?; |
| 319 | + |
| 320 | + // Send completion event |
| 321 | + match &result { |
| 322 | + Ok(_) => { |
| 323 | + let _ = app_handle_for_events.emit("vm-stop-complete", ()); |
| 324 | + } |
| 325 | + Err(e) => { |
| 326 | + let _ = app_handle_for_events.emit("vm-stop-error", e); |
| 327 | + } |
| 328 | + } |
| 329 | + |
| 330 | + result |
| 331 | +} |
| 332 | + |
228 | 333 | #[instrument(skip_all, err)] |
229 | 334 | pub async fn connect_to_docker_using_different_contexts(app: &AppHandle) -> Result<Docker, String> { |
230 | 335 | debug!("Trying to connect to Docker via different contexts"); |
|
0 commit comments