Unified approach: Use bootc's CStorage to pull the image, then prepare from containers-storage. This reuses the same infrastructure as LBIs.
(
repo: &ostree::Repo,
imgref: &ImageReference,
target_imgref: Option<&OstreeImageReference>,
store: &Storage,
booted_deployment: Option<&ostree::Deployment>,
)
| 564 | /// Unified approach: Use bootc's CStorage to pull the image, then prepare from containers-storage. |
| 565 | /// This reuses the same infrastructure as LBIs. |
| 566 | pub(crate) async fn prepare_for_pull_unified( |
| 567 | repo: &ostree::Repo, |
| 568 | imgref: &ImageReference, |
| 569 | target_imgref: Option<&OstreeImageReference>, |
| 570 | store: &Storage, |
| 571 | booted_deployment: Option<&ostree::Deployment>, |
| 572 | ) -> Result<PreparedPullResult> { |
| 573 | // Get or initialize the bootc container storage (same as used for LBIs) |
| 574 | let imgstore = store.get_ensure_imgstore()?; |
| 575 | |
| 576 | let image_ref_str = imgref.to_transport_image()?; |
| 577 | |
| 578 | // Always pull to ensure we have the latest image, whether from a remote |
| 579 | // registry or a locally rebuilt image |
| 580 | tracing::info!( |
| 581 | "Unified pull: pulling from transport '{}' to bootc storage", |
| 582 | &imgref.transport |
| 583 | ); |
| 584 | |
| 585 | // Pull the image into bootc containers-storage with per-layer |
| 586 | // download progress via the podman native API. |
| 587 | imgstore |
| 588 | .pull_with_progress(&image_ref_str) |
| 589 | .await |
| 590 | .context("Pulling image into bootc containers-storage")?; |
| 591 | |
| 592 | // Now create a containers-storage reference to read from bootc storage |
| 593 | tracing::info!("Unified pull: now importing from containers-storage transport"); |
| 594 | let containers_storage_imgref = ImageReference { |
| 595 | transport: "containers-storage".to_string(), |
| 596 | image: imgref.image.clone(), |
| 597 | signature: imgref.signature.clone(), |
| 598 | }; |
| 599 | let ostree_imgref = OstreeImageReference::from(containers_storage_imgref); |
| 600 | |
| 601 | // Configure the importer to use bootc storage as an additional image store |
| 602 | let mut config = new_proxy_config(); |
| 603 | let mut cmd = Command::new(skopeo_bin()); |
| 604 | // Use the physical path to bootc storage from the Storage struct |
| 605 | let storage_path = format!( |
| 606 | "{}/{}", |
| 607 | store.physical_root_path, |
| 608 | crate::podstorage::CStorage::subpath() |
| 609 | ); |
| 610 | crate::podstorage::set_additional_image_store(&mut cmd, &storage_path); |
| 611 | config.skopeo_cmd = Some(cmd); |
| 612 | |
| 613 | // Use the preparation flow with the custom config |
| 614 | let mut imp = new_importer_with_config(repo, &ostree_imgref, config, booted_deployment).await?; |
| 615 | if let Some(target) = target_imgref { |
| 616 | imp.set_target(target); |
| 617 | } |
| 618 | let prep = match imp.prepare().await? { |
| 619 | PrepareResult::AlreadyPresent(c) => { |
| 620 | println!("No changes in {imgref:#} => {}", c.manifest_digest); |
| 621 | return Ok(PreparedPullResult::AlreadyPresent(Box::new((*c).into()))); |
| 622 | } |
| 623 | PrepareResult::Ready(p) => p, |
no test coverage detected