Skip to main content

mvm_runtime/vm/
lima_state.rs

1use std::sync::OnceLock;
2
3use anyhow::{Context, Result};
4use tracing::{info, warn};
5
6use super::lima::{self, LimaStatus};
7use crate::config;
8use mvm_core::platform;
9
10/// Tracks whether we have already verified (and possibly started) the Lima VM.
11static LIMA_READY: OnceLock<bool> = OnceLock::new();
12
13/// Ensure the execution environment is ready for VM-side operations.
14///
15/// On native Linux: always returns Ok (no Lima needed).
16/// On macOS: checks Lima status and starts it if stopped.
17/// Subsequent calls return immediately (cached via `OnceLock`).
18pub fn ensure_lima_ready() -> Result<()> {
19    if !platform::current().needs_lima() {
20        return Ok(());
21    }
22
23    let ready = LIMA_READY.get_or_init(|| match check_and_start_lima() {
24        Ok(()) => true,
25        Err(e) => {
26            warn!(error = %e, "Lima VM not ready");
27            false
28        }
29    });
30
31    if *ready {
32        Ok(())
33    } else {
34        anyhow::bail!(
35            "Lima VM '{}' is not available. Run 'mvm setup' or 'mvm bootstrap' first.",
36            config::VM_NAME
37        )
38    }
39}
40
41fn check_and_start_lima() -> Result<()> {
42    let status = lima::get_status().with_context(|| "Failed to check Lima VM status")?;
43
44    match status {
45        LimaStatus::Running => {
46            info!("Lima VM is running");
47            Ok(())
48        }
49        LimaStatus::Stopped => {
50            info!("Lima VM is stopped, starting...");
51            lima::start().with_context(|| "Failed to start Lima VM")?;
52            info!("Lima VM started");
53            Ok(())
54        }
55        LimaStatus::NotFound => {
56            anyhow::bail!("Lima VM not found. Run 'mvm setup' first.")
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_lima_ready_static_exists() {
67        // Just verify the OnceLock compiles and is accessible
68        let _ = LIMA_READY.get();
69    }
70}