MCPcopy Create free account
hub / github.com/bootc-dev/bootc / pull_via_api

Method pull_via_api

crates/lib/src/podman_client.rs:183–243  ·  view source on GitHub ↗

Pull using the libpod HTTP API (docker transport only).

(&self, image: &str)

Source from the content-addressed store, hash-verified

181
182 /// Pull using the libpod HTTP API (docker transport only).
183 async fn pull_via_api(&self, image: &str) -> Result<()> {
184 let stream = tokio::net::UnixStream::connect(&self.socket_path)
185 .await
186 .context("Connecting to podman API socket")?;
187 let io = hyper_util::rt::TokioIo::new(stream);
188
189 let (mut sender, conn) = hyper::client::conn::http1::handshake(io)
190 .await
191 .context("HTTP/1.1 handshake with podman")?;
192
193 tokio::spawn(async move {
194 if let Err(e) = conn.await {
195 tracing::warn!("Podman HTTP connection error: {e}");
196 }
197 });
198
199 let encoded_ref =
200 percent_encoding::utf8_percent_encode(image, percent_encoding::NON_ALPHANUMERIC);
201 let uri = format!(
202 "/{LIBPOD_API_VERSION}/libpod/images/pull?reference={encoded_ref}&pullProgress=true&policy=always"
203 );
204
205 tracing::debug!("POST {uri}");
206 let response = sender
207 .send_request(
208 hyper::Request::builder()
209 .method(hyper::Method::POST)
210 .uri(&uri)
211 .header(hyper::header::HOST, "d")
212 .body(http_body_util::Empty::<hyper::body::Bytes>::new())
213 .context("Building pull request")?,
214 )
215 .await
216 .context("Sending pull request to podman")?;
217
218 let status = response.status();
219 if !status.is_success() {
220 let body = response
221 .into_body()
222 .collect()
223 .await
224 .context("Reading error response body")?
225 .to_bytes();
226 anyhow::bail!(
227 "Podman libpod pull failed with HTTP {status}: {}",
228 String::from_utf8_lossy(&body)
229 );
230 }
231
232 // Turn the HTTP body into an AsyncBufRead so we can use read_line().
233 let body_stream =
234 http_body_util::BodyStream::new(response.into_body()).filter_map(|r| async {
235 match r {
236 Ok(frame) => frame.into_data().ok().map(|b| Ok::<_, std::io::Error>(b)),
237 Err(e) => Some(Err(std::io::Error::other(e))),
238 }
239 });
240 let reader = tokio_util::io::StreamReader::new(body_stream);

Callers 1

pull_with_progressMethod · 0.80

Calls 2

spawnFunction · 0.85
display_pull_progressFunction · 0.85

Tested by

no test coverage detected