MCPcopy Create free account
hub / github.com/Dstack-TEE/dstack / fetch_manifest_inner

Function fetch_manifest_inner

vmm/src/app/registry.rs:164–212  ·  view source on GitHub ↗
(
    client: &Client,
    registry: &str,
    repo: &str,
    tag: &str,
    token: Option<&str>,
)

Source from the content-addressed store, hash-verified

162}
163
164async fn fetch_manifest_inner(
165 client: &Client,
166 registry: &str,
167 repo: &str,
168 tag: &str,
169 token: Option<&str>,
170) -> Result<OciManifest> {
171 let url = format!("https://{registry}/v2/{repo}/manifests/{tag}");
172
173 let mut req = client.get(&url).header(
174 "Accept",
175 "application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.list.v2+json",
176 );
177 if let Some(t) = token {
178 req = req.bearer_auth(t);
179 }
180
181 let response = req.send().await.context("failed to fetch manifest")?;
182
183 if !response.status().is_success() {
184 bail!(
185 "failed to fetch manifest: HTTP {} {}",
186 response.status(),
187 response.text().await.unwrap_or_default()
188 );
189 }
190
191 // Try to parse as a single manifest first
192 let body = response.text().await?;
193 if let Ok(manifest) = serde_json::from_str::<OciManifest>(&body) {
194 if !manifest.layers.is_empty() {
195 return Ok(manifest);
196 }
197 }
198
199 // Might be an index/manifest list — pick the first manifest
200 if let Ok(index) = serde_json::from_str::<OciIndex>(&body) {
201 if let Some(first) = index.manifests.into_iter().find(|m| {
202 // Prefer the non-attestation manifest
203 !m.media_type
204 .as_deref()
205 .is_some_and(|mt| mt.contains("attestation"))
206 }) {
207 return fetch_manifest(client, registry, repo, &first.digest, token).await;
208 }
209 }
210
211 bail!("unsupported manifest format");
212}
213
214/// Download and extract all layer blobs into `dest`.
215async fn download_and_extract_layers(

Callers 1

fetch_manifestFunction · 0.85

Calls 7

fetch_manifestFunction · 0.85
sendMethod · 0.80
into_iterMethod · 0.80
containsMethod · 0.80
getMethod · 0.45
statusMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected