(
client: &OciClient,
reference: &Reference,
image_ref: &str,
staging_dir: &Path,
layer: OciDescriptor,
index: usize,
)
| 3621 | } |
| 3622 | |
| 3623 | async fn download_registry_layer_blob( |
| 3624 | client: &OciClient, |
| 3625 | reference: &Reference, |
| 3626 | image_ref: &str, |
| 3627 | staging_dir: &Path, |
| 3628 | layer: OciDescriptor, |
| 3629 | index: usize, |
| 3630 | ) -> Result<DownloadedRegistryLayer, Status> { |
| 3631 | let digest_component = sanitize_image_identity(&layer.digest); |
| 3632 | let blob_path = staging_dir |
| 3633 | .join("layers") |
| 3634 | .join(format!("{index:02}-{digest_component}.blob")); |
| 3635 | let layer_root = staging_dir |
| 3636 | .join("layers") |
| 3637 | .join(format!("{index:02}-{digest_component}.root")); |
| 3638 | |
| 3639 | let mut file = tokio::fs::File::create(&blob_path) |
| 3640 | .await |
| 3641 | .map_err(|err| Status::internal(format!("create layer blob failed: {err}")))?; |
| 3642 | client |
| 3643 | .pull_blob(reference, &layer, &mut file) |
| 3644 | .await |
| 3645 | .map_err(|err| { |
| 3646 | Status::failed_precondition(format!( |
| 3647 | "failed to download layer '{}' for vm sandbox image '{image_ref}': {err}", |
| 3648 | layer.digest |
| 3649 | )) |
| 3650 | })?; |
| 3651 | file.flush() |
| 3652 | .await |
| 3653 | .map_err(|err| Status::internal(format!("flush layer blob failed: {err}")))?; |
| 3654 | |
| 3655 | let blob_path_for_digest = blob_path.clone(); |
| 3656 | let expected_digest = layer.digest.clone(); |
| 3657 | tokio::task::spawn_blocking(move || { |
| 3658 | verify_descriptor_digest(&blob_path_for_digest, &expected_digest) |
| 3659 | }) |
| 3660 | .await |
| 3661 | .map_err(|err| Status::internal(format!("layer digest verification panicked: {err}")))? |
| 3662 | .map_err(|err| { |
| 3663 | Status::failed_precondition(format!( |
| 3664 | "vm sandbox image layer verification failed for '{}': {err}", |
| 3665 | layer.digest |
| 3666 | )) |
| 3667 | })?; |
| 3668 | |
| 3669 | let blob_path_for_unpack = blob_path.clone(); |
| 3670 | let layer_root_for_unpack = layer_root.clone(); |
| 3671 | let media_type = layer.media_type.clone(); |
| 3672 | tokio::task::spawn_blocking(move || { |
| 3673 | extract_layer_blob_to_dir(&blob_path_for_unpack, &media_type, &layer_root_for_unpack) |
| 3674 | }) |
| 3675 | .await |
| 3676 | .map_err(|err| Status::internal(format!("layer extraction panicked: {err}")))? |
| 3677 | .map_err(|err| { |
| 3678 | Status::failed_precondition(format!( |
| 3679 | "failed to extract layer '{}' for vm sandbox image '{image_ref}': {err}", |
| 3680 | layer.digest |
no test coverage detected