Skip to content

Commit

Permalink
container: Make layering more directly re-use unencapsulation
Browse files Browse the repository at this point in the history
This came out of some prep work on
ostreedev#69

Right now it's confusing, the layering code ended up re-implementing
the "fetch and unpack tarball" logic from the unencapsulation path
unnecessarily.

I think it's much clearer if the layering path just calls down
into the unencapsulation path first.

Among other things this will also ensure we're honoring the image
verification string.
  • Loading branch information
cgwalters committed Dec 13, 2021
1 parent 6fa7fb9 commit 27887c7
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 16 deletions.
25 changes: 13 additions & 12 deletions lib/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,34 +264,35 @@ impl LayeredImageImporter {
pub async fn import(self, import: Box<PreparedImport>) -> Result<LayeredImageState> {
let mut proxy = self.proxy;
let target_imgref = self.target_imgref.as_ref().unwrap_or(&self.imgref);
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(
let base_commit = super::unencapsulate_from_manifest_impl(
&self.repo,
&mut proxy,
&self.proxy_img,
&base_layer.layer,
target_imgref,
&import.manifest,
None,
true,
)
.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
// Write the ostree ref for that single layer; TODO
// handle this as part of the overall transaction.
self.repo.set_ref_immediate(
None,
base_layer.ostree_ref.as_str(),
Some(commit.as_str()),
Some(base_commit.as_str()),
gio::NONE_CANCELLABLE,
)?;
commit
base_commit
};

let ostree_ref = ref_for_image(&target_imgref.imgref)?;

let mut layer_commits = Vec::new();
let mut layer_filtered_content: MetaFilteredData = HashMap::new();
for layer in import.layers {
Expand Down
18 changes: 14 additions & 4 deletions lib/src/container/unencapsulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -222,20 +223,28 @@ 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<UnencapsulateOptions>,
ignore_layered: bool,
) -> Result<String> {
if matches!(imgref.sigverify, SignatureSource::ContainerPolicy)
&& skopeo::container_policy_is_default_insecure()?
{
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)
.ok_or_else(|| anyhow!("No layers in image"))?
} else {
require_one_layer_blob(manifest)?
};
event!(
Level::DEBUG,
"target blob digest:{} size: {}",
Expand Down Expand Up @@ -272,7 +281,8 @@ pub async fn unencapsulate_from_manifest(
options: Option<UnencapsulateOptions>,
) -> Result<String> {
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)
Expand Down

0 comments on commit 27887c7

Please sign in to comment.