ironflow_ops_docker/containers/
lifecycle.rs1use async_trait::async_trait;
4use bollard::Docker;
5use bollard::query_parameters::{RestartContainerOptions, StopContainerOptions};
6use ironflow_core::error::OperationError;
7use ironflow_core::operation::{Operation, OperationContext, TypedOperation};
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10
11use crate::containers::DockerRef;
12use crate::helpers::{docker_error, to_value};
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct ContainerStartOutput {
21 pub container: String,
23}
24
25pub struct ContainerStart {
39 docker: Docker,
40 container: String,
41}
42
43impl ContainerStart {
44 pub fn new(client: impl Into<DockerRef>, container: impl Into<String>) -> Self {
46 Self {
47 docker: client.into().0,
48 container: container.into(),
49 }
50 }
51
52 pub async fn run(
59 &self,
60 _ctx: &OperationContext,
61 ) -> Result<ContainerStartOutput, OperationError> {
62 self.docker
63 .start_container(
64 &self.container,
65 None::<bollard::query_parameters::StartContainerOptions>,
66 )
67 .await
68 .map_err(docker_error)?;
69 Ok(ContainerStartOutput {
70 container: self.container.clone(),
71 })
72 }
73}
74
75#[async_trait]
76impl Operation for ContainerStart {
77 fn kind(&self) -> &str {
78 "docker"
79 }
80
81 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
82 to_value(&self.run(ctx).await?)
83 }
84
85 fn input(&self) -> Option<Value> {
86 Some(serde_json::json!({
87 "operation": "container_start",
88 "container": self.container,
89 }))
90 }
91}
92
93impl TypedOperation for ContainerStart {
94 type Output = ContainerStartOutput;
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct ContainerStopOutput {
104 pub container: String,
106}
107
108pub struct ContainerStop {
122 docker: Docker,
123 container: String,
124 timeout: Option<i64>,
125}
126
127impl ContainerStop {
128 pub fn new(client: impl Into<DockerRef>, container: impl Into<String>) -> Self {
130 Self {
131 docker: client.into().0,
132 container: container.into(),
133 timeout: None,
134 }
135 }
136
137 pub fn timeout(mut self, secs: i64) -> Self {
139 self.timeout = Some(secs);
140 self
141 }
142
143 pub async fn run(
149 &self,
150 _ctx: &OperationContext,
151 ) -> Result<ContainerStopOutput, OperationError> {
152 let options = StopContainerOptions {
153 t: Some(self.timeout.unwrap_or(10) as i32),
154 signal: None,
155 };
156 self.docker
157 .stop_container(&self.container, Some(options))
158 .await
159 .map_err(docker_error)?;
160 Ok(ContainerStopOutput {
161 container: self.container.clone(),
162 })
163 }
164}
165
166#[async_trait]
167impl Operation for ContainerStop {
168 fn kind(&self) -> &str {
169 "docker"
170 }
171
172 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
173 to_value(&self.run(ctx).await?)
174 }
175
176 fn input(&self) -> Option<Value> {
177 Some(serde_json::json!({
178 "operation": "container_stop",
179 "container": self.container,
180 }))
181 }
182}
183
184impl TypedOperation for ContainerStop {
185 type Output = ContainerStopOutput;
186}
187
188#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct ContainerRestartOutput {
195 pub container: String,
197}
198
199pub struct ContainerRestart {
213 docker: Docker,
214 container: String,
215 timeout: Option<i64>,
216}
217
218impl ContainerRestart {
219 pub fn new(client: impl Into<DockerRef>, container: impl Into<String>) -> Self {
221 Self {
222 docker: client.into().0,
223 container: container.into(),
224 timeout: None,
225 }
226 }
227
228 pub fn timeout(mut self, secs: i64) -> Self {
230 self.timeout = Some(secs);
231 self
232 }
233
234 pub async fn run(
240 &self,
241 _ctx: &OperationContext,
242 ) -> Result<ContainerRestartOutput, OperationError> {
243 let options = RestartContainerOptions {
244 t: Some(self.timeout.unwrap_or(10) as i32),
245 signal: None,
246 };
247 self.docker
248 .restart_container(&self.container, Some(options))
249 .await
250 .map_err(docker_error)?;
251 Ok(ContainerRestartOutput {
252 container: self.container.clone(),
253 })
254 }
255}
256
257#[async_trait]
258impl Operation for ContainerRestart {
259 fn kind(&self) -> &str {
260 "docker"
261 }
262
263 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
264 to_value(&self.run(ctx).await?)
265 }
266
267 fn input(&self) -> Option<Value> {
268 Some(serde_json::json!({
269 "operation": "container_restart",
270 "container": self.container,
271 }))
272 }
273}
274
275impl TypedOperation for ContainerRestart {
276 type Output = ContainerRestartOutput;
277}