Skip to content

Commit 7783243

Browse files
authored
Merge pull request #160 from nookat-io/colima_engine_settings
[feat]: colima engine stop feature
2 parents d28a423 + 5601c1e commit 7783243

File tree

13 files changed

+430
-62
lines changed

13 files changed

+430
-62
lines changed

src-tauri/src/entities/engine/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ pub struct InstallationProgress {
9898
pub logs: Vec<String>,
9999
}
100100

101+
#[derive(Serialize, Deserialize, Debug, Clone)]
102+
pub struct ColimaEngineStopProgress {
103+
pub step: String,
104+
pub message: String,
105+
pub percentage: u8,
106+
pub logs: Vec<String>,
107+
}
108+
101109
#[derive(Serialize, Deserialize, Debug, Clone)]
102110
pub struct ColimaConfig {
103111
pub cpu: u8,

src-tauri/src/handlers/system/engine.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::entities::EngineStatus;
22
use crate::entities::{ColimaConfig, InstallationMethod};
3-
use crate::services::engine::{install_colima, start_colima_vm};
3+
use crate::services::engine::{install_colima, start_colima_vm, stop_colima_vm};
44
use crate::services::shell::{is_colima_available, is_homebrew_available};
55
use crate::state::SharedEngineState;
66
use tauri::State;
@@ -44,6 +44,13 @@ pub async fn start_colima_vm_command(
4444
start_colima_vm(&app, config).await
4545
}
4646

47+
#[tauri::command]
48+
#[instrument(skip_all, err)]
49+
pub async fn stop_colima_vm_command(app: tauri::AppHandle) -> Result<(), String> {
50+
info!("Stopping Colima VM");
51+
stop_colima_vm(&app).await
52+
}
53+
4754
#[tauri::command]
4855
#[instrument(skip_all, err)]
4956
pub async fn check_colima_availability(app: tauri::AppHandle) -> Result<bool, String> {

src-tauri/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use crate::handlers::{
5454
start_colima_vm_command,
5555
start_container,
5656
start_engine_state_monitoring,
57+
stop_colima_vm_command,
5758
stop_container,
5859
unpause_container,
5960
update_language,
@@ -197,6 +198,7 @@ pub fn run() {
197198
check_colima_availability,
198199
install_colima_command,
199200
start_colima_vm_command,
201+
stop_colima_vm_command,
200202
])
201203
.setup(|app| {
202204
let engine_state = SharedEngineState::new(app.app_handle().clone());

src-tauri/src/services/engine/linux.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ pub async fn start_colima_vm(_app: &AppHandle, _config: ColimaConfig) -> Result<
2323
todo!("Colima is only implemented on macOS for now, other platforms are not supported yet");
2424
}
2525

26+
pub async fn stop_colima_vm(app_handle: &AppHandle) -> Result<(), String> {
27+
todo!("Colima is only implemented on macOS for now, other platforms are not supported yet");
28+
}
29+
2630
#[instrument(skip_all, err)]
2731
pub async fn is_colima_available(_app: &AppHandle) -> Result<bool, String> {
2832
// Colima is only implemented on macOS for now, other platforms are not supported yet

src-tauri/src/services/engine/macos.rs

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use crate::entities::{ColimaConfig, InstallationMethod, InstallationProgress};
1+
use crate::entities::{
2+
ColimaConfig, ColimaEngineStopProgress, InstallationMethod, InstallationProgress,
3+
};
24
use crate::services::shell::{
35
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,
57
};
68
use bollard::Docker;
79
use tauri::{AppHandle, Emitter};
@@ -225,6 +227,109 @@ pub async fn start_colima_vm(app_handle: &AppHandle, config: ColimaConfig) -> Re
225227
result
226228
}
227229

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+
228333
#[instrument(skip_all, err)]
229334
pub async fn connect_to_docker_using_different_contexts(app: &AppHandle) -> Result<Docker, String> {
230335
debug!("Trying to connect to Docker via different contexts");

src-tauri/src/services/engine/windows.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ pub async fn start_colima_vm(_app: &AppHandle, _config: ColimaConfig) -> Result<
2121
todo!("Colima is only implemented on macOS for now, other platforms are not supported yet");
2222
}
2323

24+
pub async fn stop_colima_vm(app_handle: &AppHandle) -> Result<(), String> {
25+
todo!("Colima is only implemented on macOS for now, other platforms are not supported yet");
26+
}
27+
2428
#[instrument(skip_all, err)]
2529
pub async fn is_colima_available(_app: &AppHandle) -> Result<bool, String> {
2630
// Colima is only implemented on macOS for now, other platforms are not supported yet

src-tauri/src/services/shell/macos.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,28 @@ pub async fn check_colima_status(app: &AppHandle) -> Result<bool, String> {
211211
Ok(status_text.contains("Running"))
212212
}
213213

214+
#[instrument(skip_all, err)]
215+
pub async fn stop_colima(app: &AppHandle) -> Result<(), String> {
216+
debug!("Stopping Colima");
217+
debug!("Executing: colima stop");
218+
219+
let output = app
220+
.shell()
221+
.command("zsh")
222+
.args(["-l", "-c", "colima stop"])
223+
.output()
224+
.await
225+
.map_err(|e| format!("Failed to stop Colima: {}", e))?;
226+
227+
if !output.status.success() {
228+
let stderr = String::from_utf8_lossy(&output.stderr);
229+
return Err(format!("Failed to stop Colima: {}", stderr));
230+
}
231+
232+
debug!("Colima stopped successfully");
233+
Ok(())
234+
}
235+
214236
/// Start Colima VM with configuration
215237
#[instrument(skip_all, err)]
216238
pub async fn start_colima_with_config(

0 commit comments

Comments
 (0)