loam_cli/commands/dev/
docker.rs

1use soroban_cli::{commands as cli, CommandParser};
2use std::error::Error;
3
4pub async fn start_local_stellar() -> Result<(), Box<dyn Error>> {
5    let result = cli::container::StartCmd::parse_arg_vec(&["local"])?
6        .run(&soroban_cli::commands::global::Args::default())
7        .await;
8
9    match result {
10        Ok(()) => {
11            tokio::time::sleep(std::time::Duration::from_secs(10)).await;
12        }
13        Err(e) => {
14            if e.to_string().contains("already in use")
15                || e.to_string().contains("port is already allocated")
16            {
17                eprintln!("Container is already running, proceeding to health check...");
18            } else {
19                return Err(Box::new(e));
20            }
21        }
22    }
23
24    wait_for_stellar_health().await?;
25    Ok(())
26}
27async fn wait_for_stellar_health() -> Result<(), Box<dyn Error>> {
28    let client = reqwest::Client::new();
29    let start_time = std::time::Instant::now();
30    let timeout = std::time::Duration::from_secs(60);
31    loop {
32        let elapsed_time = start_time.elapsed();
33        if elapsed_time > timeout {
34            eprintln!("Timeout reached: stopping health checks.");
35            return Err("Health check timed out".into());
36        }
37        let res = client
38            .post("http://localhost:8000/rpc")
39            .header("Content-Type", "application/json")
40            .body(r#"{"jsonrpc": "2.0", "id": 1, "method": "getHealth"}"#)
41            .send()
42            .await?;
43        if res.status().is_success() {
44            let health_status: serde_json::Value = res.json().await?;
45            if health_status["result"]["status"] == "healthy" {
46                break;
47            }
48            eprintln!("Stellar status is not healthy: {health_status:?}");
49        } else {
50            eprintln!("Health check request failed with status: {}", res.status());
51        }
52        tokio::time::sleep(std::time::Duration::from_secs(5)).await;
53        eprintln!("Retrying health check.");
54    }
55    Ok(())
56}