firecracker_sdk/infrastructure/process/
mod.rs

1use std::{env, time::Duration};
2
3use anyhow::Result;
4use tokio::process::{Child, Command};
5
6use crate::{
7    domain::config::FirecrackerConfiguration,
8    infrastructure::connection::{socket::Socket, stream::Stream},
9};
10
11/// Structure for managing the Firecracker process created using `FirecrackerStartup`
12pub struct FirecrackerProcess {
13    process: Child,
14    stream: Stream,
15    configuration: FirecrackerConfiguration,
16}
17
18impl FirecrackerProcess {
19    pub(crate) async fn new(configuration: FirecrackerConfiguration) -> Result<Self> {
20        Ok(Self {
21            process: {
22                let child = Command::new(env::var("FIRECRACKER").unwrap_or("firecracker".into()))
23                    .args([
24                        "--api-sock",
25                        configuration
26                            .startup_config
27                            .get_api_socket()
28                            .to_str()
29                            .unwrap(),
30                    ])
31                    .spawn()?;
32                tokio::time::sleep(Duration::from_millis(2)).await;
33                child
34            },
35            stream: Socket::new()?
36                .connect(configuration.startup_config.get_api_socket())
37                .await?,
38            configuration,
39        })
40    }
41
42    pub fn get_config(&self) -> &FirecrackerConfiguration {
43        &self.configuration
44    }
45
46    /// Correctly starts the process stop and waits for it to complete
47    pub async fn stop(mut self) -> Result<()> {
48        self.stream.close().await?;
49        self.process.kill().await?;
50        Ok(())
51    }
52}