Run a short lived container.
(&self, cmd: &str)
| 94 | |
| 95 | /// Run a short lived container. |
| 96 | pub async fn run_cmd(&self, cmd: &str) -> anyhow::Result<Vec<String>> { |
| 97 | let cmdv = split_cmd(cmd); |
| 98 | |
| 99 | let config = Config { |
| 100 | image: Some(self.image.clone()), |
| 101 | user: Some(self.user.to_string()), |
| 102 | cmd: Some(cmdv), |
| 103 | attach_stderr: Some(true), |
| 104 | attach_stdout: Some(true), |
| 105 | tty: Some(true), |
| 106 | labels: Some(self.labels()), |
| 107 | env: Some(self.env()), |
| 108 | host_config: Some(HostConfig { |
| 109 | // We'll remove it explicitly at the end after collecting the output. |
| 110 | auto_remove: Some(false), |
| 111 | init: Some(true), |
| 112 | binds: Some( |
| 113 | self.volumes |
| 114 | .iter() |
| 115 | .map(|(h, c)| format!("{}:{c}", h.to_string_lossy())) |
| 116 | .collect(), |
| 117 | ), |
| 118 | network_mode: self.network_name.clone(), |
| 119 | ..Default::default() |
| 120 | }), |
| 121 | ..Default::default() |
| 122 | }; |
| 123 | |
| 124 | let id = self |
| 125 | .docker |
| 126 | .create_container::<&str, _>(None, config) |
| 127 | .await |
| 128 | .context("failed to create container")? |
| 129 | .id; |
| 130 | |
| 131 | let AttachContainerResults { mut output, .. } = self |
| 132 | .docker |
| 133 | .attach_container::<String>( |
| 134 | &id, |
| 135 | Some(AttachContainerOptions { |
| 136 | stdout: Some(true), |
| 137 | stderr: Some(true), |
| 138 | stream: Some(true), |
| 139 | ..Default::default() |
| 140 | }), |
| 141 | ) |
| 142 | .await |
| 143 | .context("failed to attach to container")?; |
| 144 | |
| 145 | self.docker |
| 146 | .start_container::<&str>(&id, None) |
| 147 | .await |
| 148 | .context("failed to start container")?; |
| 149 | |
| 150 | // Collect docker attach output |
| 151 | let mut out = Vec::new(); |
| 152 | while let Some(Ok(output)) = output.next().await { |
| 153 | out.push(output.to_string()); |