firecracker_sdk/firecracker/
mod.rs

1use anyhow::Result;
2use tokio::{
3    io::{AsyncReadExt, AsyncWriteExt},
4    net::UnixStream,
5};
6
7pub mod firecracker_configuration;
8pub mod firecracker_socket;
9pub mod firercracker_process;
10
11/// A structure that allows you to work safely with VMs
12///
13/// Exemple:
14/// ```no_run
15/// let vm_process = FirecrackerStartup::new()
16///     .api_sock("/tmp/some.socket")
17///     .start().unwrap();
18///
19/// let firecracker_socket = FirecrackerSocket::new().unwrap();
20/// let firecracker_stream = firecracker_socket.connect("/tmp/some.socket");
21/// ```
22#[allow(unused)]
23pub struct FirecrackerStream {
24    stream: UnixStream,
25}
26
27#[allow(unused)]
28impl FirecrackerStream {
29    pub(crate) fn new(stream: UnixStream) -> Self {
30        Self { stream }
31    }
32
33    async fn send_raw(&mut self, raw: &[u8]) -> Result<()> {
34        self.stream.write_all(raw).await?;
35        Ok(())
36    }
37
38    async fn read_raw(&mut self, raw: &mut [u8]) -> Result<usize> {
39        Ok(self.stream.read(raw).await?)
40    }
41
42    /// Safely closes the unix stream
43    pub async fn close(mut self) -> Result<()> {
44        self.stream.shutdown().await?;
45        Ok(())
46    }
47}
48
49#[cfg(test)]
50mod tests {
51
52    use anyhow::Result;
53    use tempfile::tempdir;
54    use tokio::{
55        io::{AsyncReadExt, AsyncWriteExt},
56        join,
57        net::UnixListener,
58    };
59
60    use crate::firecracker::firecracker_socket::FirecrackerSocket;
61
62    #[tokio::test]
63    async fn unix_socket_connect_test() -> Result<()> {
64        let dir = tempdir()?;
65        let socket = dir.path().join("echo.socket");
66        let lis = UnixListener::bind(&socket)?;
67
68        assert!(socket.exists());
69
70        let server = tokio::spawn(async move {
71            let (mut socket, _) = lis.accept().await?;
72            let mut buf = [0u8; 64];
73            let n = socket.read(&mut buf).await?;
74            assert_eq!(&buf[..n], b"ping");
75            socket.write_all(b"pong").await?;
76            Ok::<_, anyhow::Error>(())
77        });
78
79        let mut client = FirecrackerSocket::new()?.connect(socket).await?;
80        client.send_raw(b"ping").await?;
81        let mut buf = [0u8; 64];
82        let n = client.read_raw(&mut buf).await?;
83        assert_eq!(&buf[..n], b"pong");
84
85        join!(server).0??;
86
87        dir.close()?;
88        Ok(())
89    }
90}