use foundation_netio::PreparedRequestBuilder;
use crate::client::body::LogStream;
use crate::error::DockerError;
use crate::generated::exec::{container_exec_request, ContainerExecArgs, ContainerExecRequest};
use crate::generated::start::{exec_start_request, ExecStartArgs, ExecStartRequest};
use crate::generated::resize::{exec_resize_request, ExecResizeArgs};
use crate::generated::shared::IDResponse;
type NoMod = fn(&mut PreparedRequestBuilder);
pub async fn exec_create(
client: &super::DockerClient,
id: &str,
cmd: &[&str],
) -> Result<IDResponse, DockerError> {
let args = ContainerExecArgs {
id: id.to_string(),
body: ContainerExecRequest {
cmd: Some(cmd.iter().map(|c| (*c).to_string()).collect()),
attach_stdout: Some(true),
attach_stderr: Some(true),
..ContainerExecRequest::default()
},
};
let response =
container_exec_request(client.api(), &args, &client.api_url().await?, None::<NoMod>).await?;
Ok(response.body)
}
pub async fn exec_start(
client: &super::DockerClient,
id: &str,
detach: bool,
) -> Result<LogStream, DockerError> {
let args = ExecStartArgs {
id: id.to_string(),
body: ExecStartRequest {
detach: Some(detach),
..ExecStartRequest::default()
},
};
let response =
exec_start_request(client.api(), &args, &client.api_url().await?, None::<NoMod>).await?;
Ok(LogStream::new(response.body, client.limits().max_log_frame))
}
pub async fn exec_inspect(
client: &super::DockerClient,
id: &str,
) -> Result<serde_json::Value, DockerError> {
let endpoint_url = format!("{}/exec/{}/json", client.api_url().await?, id);
let builder = PreparedRequestBuilder::get(&endpoint_url)
.map_err(|e| DockerError::Transport(e.to_string()))?;
let response = client
.http()
.send_async(builder.build())
.await
.map_err(|e| DockerError::Transport(e.to_string()))?;
let status: usize = response.get_status().into();
if status < 200 || status >= 300 {
return Err(DockerError::Api {
status: status as u16,
message: format!("exec_inspect failed with status {status}"),
});
}
let body_bytes =
foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(
response.take_body(),
);
let parsed: serde_json::Value = serde_json::from_slice(&body_bytes)
.map_err(|e| DockerError::JsonParse(format!("exec_inspect: {e}")))?;
Ok(parsed)
}
pub async fn exec_resize(
client: &super::DockerClient,
id: &str,
h: u32,
w: u32,
) -> Result<(), DockerError> {
let args = ExecResizeArgs {
id: id.to_string(),
h: Some(h.to_string()),
w: Some(w.to_string()),
};
exec_resize_request(client.api(), &args, &client.api_url().await?, None::<NoMod>).await?;
Ok(())
}