firecracker_sdk/vm/
mod.rs

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