diff --git a/lib/src/container/store.rs b/lib/src/container/store.rs index 28525f9f..28056767 100644 --- a/lib/src/container/store.rs +++ b/lib/src/container/store.rs @@ -264,33 +264,28 @@ impl LayeredImageImporter { pub async fn import(self, import: Box) -> Result { let mut proxy = self.proxy; let target_imgref = self.target_imgref.as_ref().unwrap_or(&self.imgref); + + // First, we need the base ostree commit, which we then can use + // for e.g. performing SELinux labeling and other things. + // Delegate to the core unencapsulation code to deserialize the commit. + let base_commit = super::unencapsulate_from_manifest_impl( + &self.repo, + &mut proxy, + target_imgref, + &import.manifest, + None, + true, + ) + .await?; + // Write the ostree ref for that single layer. + self.repo.set_ref_immediate( + None, + import.base_layer.ostree_ref.as_str(), + Some(base_commit.as_str()), + gio::NONE_CANCELLABLE, + )?; + let ostree_ref = ref_for_image(&target_imgref.imgref)?; - // First download the base image (if necessary) - we need the SELinux policy - // there to label all following layers. - let base_layer = import.base_layer; - let base_commit = if let Some(c) = base_layer.commit { - c - } else { - let base_layer_ref = &base_layer.layer; - let (blob, driver) = super::unencapsulate::fetch_layer_decompress( - &mut proxy, - &self.proxy_img, - &base_layer.layer, - ) - .await?; - let importer = crate::tar::import_tar(&self.repo, blob, None); - let commit = super::unencapsulate::join_fetch(importer, driver) - .await - .with_context(|| format!("Parsing blob {}", base_layer_ref.digest()))?; - // TODO support ref writing in tar import - self.repo.set_ref_immediate( - None, - base_layer.ostree_ref.as_str(), - Some(commit.as_str()), - gio::NONE_CANCELLABLE, - )?; - commit - }; let mut layer_commits = Vec::new(); let mut layer_filtered_content: MetaFilteredData = HashMap::new(); diff --git a/lib/src/container/unencapsulate.rs b/lib/src/container/unencapsulate.rs index 880ee522..a46358ca 100644 --- a/lib/src/container/unencapsulate.rs +++ b/lib/src/container/unencapsulate.rs @@ -183,7 +183,8 @@ pub async fn unencapsulate( let mut proxy = ImageProxy::new().await?; let (manifest, image_digest) = fetch_manifest_impl(&mut proxy, imgref).await?; let ostree_commit = - unencapsulate_from_manifest_impl(repo, &mut proxy, imgref, &manifest, options).await?; + unencapsulate_from_manifest_impl(repo, &mut proxy, imgref, &manifest, options, false) + .await?; Ok(Import { ostree_commit, image_digest, @@ -222,12 +223,13 @@ pub(crate) async fn fetch_layer_decompress<'a>( Ok((blob, driver)) } -async fn unencapsulate_from_manifest_impl( +pub(crate) async fn unencapsulate_from_manifest_impl( repo: &ostree::Repo, proxy: &mut ImageProxy, imgref: &OstreeImageReference, manifest: &oci_spec::image::ImageManifest, options: Option, + ignore_layered: bool, ) -> Result { if matches!(imgref.sigverify, SignatureSource::ContainerPolicy) && skopeo::container_policy_is_default_insecure()? @@ -235,7 +237,11 @@ async fn unencapsulate_from_manifest_impl( return Err(anyhow!("containers-policy.json specifies a default of `insecureAcceptAnything`; refusing usage")); } let options = options.unwrap_or_default(); - let layer = require_one_layer_blob(manifest)?; + let layer = if ignore_layered { + manifest.layers().get(0).unwrap() + } else { + require_one_layer_blob(manifest)? + }; event!( Level::DEBUG, "target blob digest:{} size: {}", @@ -272,7 +278,8 @@ pub async fn unencapsulate_from_manifest( options: Option, ) -> Result { let mut proxy = ImageProxy::new().await?; - let r = unencapsulate_from_manifest_impl(repo, &mut proxy, imgref, manifest, options).await?; + let r = unencapsulate_from_manifest_impl(repo, &mut proxy, imgref, manifest, options, false) + .await?; // FIXME write ostree commit after proxy finalization proxy.finalize().await?; Ok(r)