docker_pyo3/exec.rs
1use docker_api::models::ExecInspect200Response;
2use docker_api::opts::ExecResizeOpts;
3use docker_api::Exec;
4use pyo3::exceptions;
5use pyo3::prelude::*;
6use pythonize::pythonize;
7
8use crate::Pyo3Docker;
9
10#[pymodule]
11pub fn exec(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
12 m.add_class::<Pyo3Exec>()?;
13 Ok(())
14}
15
16/// Represents a Docker exec instance for running commands in containers.
17///
18/// Use this to inspect or resize an exec session that was created with
19/// Container.exec_create().
20#[pyclass(name = "Exec")]
21pub struct Pyo3Exec {
22 exec: Exec,
23 exec_id: String,
24}
25
26#[pymethods]
27impl Pyo3Exec {
28 #[new]
29 /// Get an existing exec instance by ID.
30 ///
31 /// Args:
32 /// docker: Docker client instance
33 /// id: Exec instance ID
34 ///
35 /// Returns:
36 /// Exec: Exec instance
37 pub fn new(docker: Pyo3Docker, id: &str) -> Self {
38 Pyo3Exec {
39 exec: Exec::get(docker.0, id),
40 exec_id: id.to_string(),
41 }
42 }
43
44 /// Get the exec instance ID.
45 ///
46 /// Returns:
47 /// str: Exec instance ID
48 pub fn id(&self) -> String {
49 self.exec_id.clone()
50 }
51
52 /// Inspect the exec instance to get detailed information.
53 ///
54 /// Returns information about the exec instance including its running state,
55 /// exit code, process config, and container ID.
56 ///
57 /// Returns:
58 /// dict: Detailed exec information including:
59 /// - id: Exec instance ID
60 /// - running: Whether the exec is running
61 /// - exit_code: Exit code (if completed)
62 /// - process_config: Command and environment
63 /// - container_id: ID of the container
64 ///
65 /// Raises:
66 /// SystemError: If inspect fails
67 pub fn inspect(&self) -> PyResult<Py<PyAny>> {
68 let rv = __exec_inspect(&self.exec);
69 match rv {
70 Ok(rv) => Ok(pythonize_this!(rv)),
71 Err(rv) => Err(py_sys_exception!(rv)),
72 }
73 }
74
75 /// Resize the TTY session for this exec instance.
76 ///
77 /// This only works if the exec was created with tty=True.
78 /// Use this to adjust terminal dimensions for interactive sessions.
79 ///
80 /// Args:
81 /// width: New terminal width in columns
82 /// height: New terminal height in rows
83 ///
84 /// Returns:
85 /// None
86 ///
87 /// Raises:
88 /// SystemError: If resize fails (e.g., exec not created with TTY)
89 #[pyo3(signature = (width, height))]
90 pub fn resize(&self, width: u64, height: u64) -> PyResult<()> {
91 let opts = ExecResizeOpts::builder()
92 .width(width)
93 .height(height)
94 .build();
95 let rv = __exec_resize(&self.exec, &opts);
96 match rv {
97 Ok(_) => Ok(()),
98 Err(rv) => Err(py_sys_exception!(rv)),
99 }
100 }
101}
102
103#[tokio::main]
104async fn __exec_inspect(exec: &Exec) -> Result<ExecInspect200Response, docker_api::Error> {
105 exec.inspect().await
106}
107
108#[tokio::main]
109async fn __exec_resize(exec: &Exec, opts: &ExecResizeOpts) -> Result<(), docker_api::Error> {
110 exec.resize(opts).await
111}