firecracker_http_client/
lib.rs1use crate::{action::InstanceActionInfo, error::FirecrackerError};
2use reqwest::{Client, StatusCode};
3use url::Url;
4
5#[cfg(test)]
6mod tests;
7
8pub mod action;
9pub mod balloon;
10pub mod boot;
11pub mod cpu;
12pub mod drive;
13pub mod entropy;
14pub mod error;
15pub mod instance;
16pub mod logger;
17pub mod machine;
18pub mod metrics;
19pub mod mmds;
20pub mod models;
21pub mod network;
22pub mod snapshot;
23pub mod validation;
24pub mod version;
25pub mod vm;
26pub mod vsock;
27
28pub use drive::DriveOperations;
29pub use models::*;
30pub use network::NetworkInterfaceOperations;
31pub use snapshot::SnapshotOperations;
32pub use vm::VmOperations;
33
34pub struct FirecrackerClient {
35 base_url: String,
36 client: Client,
37}
38
39impl FirecrackerClient {
40 pub async fn new(base_url: &str) -> Result<Self, FirecrackerError> {
41 Ok(Self {
42 base_url: base_url.to_string(),
43 client: Client::new(),
44 })
45 }
46
47 pub(crate) fn url(&self, path: &str) -> Result<Url, FirecrackerError> {
48 let url = format!(
49 "{}/{}",
50 self.base_url.trim_end_matches('/'),
51 path.trim_start_matches('/')
52 );
53 Url::parse(&url).map_err(FirecrackerError::UrlParseError)
54 }
55
56 pub async fn create_sync_action(
57 &self,
58 action: &InstanceActionInfo,
59 ) -> Result<(), FirecrackerError> {
60 let url = self.url("/actions")?;
61
62 let response = self.client.put(url).json(&action).send().await?;
63
64 match response.status() {
65 StatusCode::NO_CONTENT => Ok(()),
66 status => {
67 let error_msg = response.text().await?;
68 Err(FirecrackerError::Api {
69 status_code: status.as_u16(),
70 message: error_msg,
71 })
72 }
73 }
74 }
75}