Skip to content
This repository has been archived by the owner on Jan 15, 2025. It is now read-only.

container: Make layering more directly re-use unencapsulation #184

Merged
merged 2 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions lib/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,34 +264,36 @@ 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,
target_imgref,
&self.proxy_img,
&base_layer.layer,
&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
30 changes: 23 additions & 7 deletions lib/src/container/unencapsulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,13 @@ pub async fn unencapsulate(
options: Option<UnencapsulateOptions>,
) -> Result<Import> {
let mut proxy = ImageProxy::new().await?;
let (manifest, image_digest) = fetch_manifest_impl(&mut proxy, imgref).await?;
let oi = &proxy.open_image(&imgref.imgref.to_string()).await?;
let (image_digest, raw_manifest) = proxy.fetch_manifest(oi).await?;
let manifest = serde_json::from_slice(&raw_manifest)?;
let ostree_commit =
unencapsulate_from_manifest_impl(repo, &mut proxy, imgref, &manifest, options).await?;
unencapsulate_from_manifest_impl(repo, &mut proxy, imgref, oi, &manifest, options, false)
.await?;
proxy.close_image(oi).await?;
Ok(Import {
ostree_commit,
image_digest,
Expand Down Expand Up @@ -222,28 +226,36 @@ 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,
oi: &containers_image_proxy::OpenedImage,
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: {}",
layer.digest().as_str(),
layer.size()
);
let oi = proxy.open_image(&imgref.imgref.to_string()).await?;
let (blob, driver) = fetch_layer_decompress(proxy, &oi, layer).await?;
let (blob, driver) = fetch_layer_decompress(proxy, oi, layer).await?;
let blob = ProgressReader {
reader: blob,
progress: options.progress,
Expand Down Expand Up @@ -272,7 +284,11 @@ 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 oi = &proxy.open_image(&imgref.imgref.to_string()).await?;
let r =
unencapsulate_from_manifest_impl(repo, &mut proxy, imgref, oi, manifest, options, false)
.await?;
proxy.close_image(oi).await?;
// FIXME write ostree commit after proxy finalization
proxy.finalize().await?;
Ok(r)
Expand Down