bootc
bootc copied to clipboard
copy-to-storage: Fails for non-ostree base image
The bootc image copy-to-storage code currently requires the final-diffid from an ostree-container base.
Typed this up, but didn't test yet
diff --git a/ostree-ext/src/container/store.rs b/ostree-ext/src/container/store.rs
index 74500f36..bb6fee11 100644
--- a/ostree-ext/src/container/store.rs
+++ b/ostree-ext/src/container/store.rs
@@ -1401,13 +1401,7 @@ pub(crate) fn export_to_oci(
let srcinfo = query_image(repo, imgref)?.ok_or_else(|| anyhow!("No such image"))?;
let (commit_layer, component_layers, remaining_layers) =
parse_manifest_layout(&srcinfo.manifest, &srcinfo.configuration)?;
- let commit_layer = commit_layer.ok_or_else(|| anyhow!("Missing {DIFFID_LABEL}"))?;
- let commit_chunk_ref = ref_for_layer(commit_layer)?;
- let commit_chunk_rev = repo.require_rev(&commit_chunk_ref)?;
- let mut chunking = chunking::Chunking::new(repo, &commit_chunk_rev)?;
- for layer in component_layers {
- chunking_from_layer_committed(repo, layer, &mut chunking)?;
- }
+
// Unfortunately today we can't guarantee we reserialize the same tar stream
// or compression, so we'll need to generate a new copy of the manifest and config
// with the layers reset.
@@ -1417,8 +1411,6 @@ pub(crate) fn export_to_oci(
new_config.history_mut().clear();
new_config.rootfs_mut().diff_ids_mut().clear();
- let mut dest_oci = ocidir::OciDir::ensure(dest_oci)?;
-
let opts = ExportOpts {
skip_compression: opts.skip_compression,
authfile: opts.authfile,
@@ -1427,19 +1419,36 @@ pub(crate) fn export_to_oci(
let mut labels = HashMap::new();
- // Given the object chunking information we recomputed from what
- // we found on disk, re-serialize to layers (tarballs).
- export_chunked(
- repo,
- &srcinfo.base_commit,
- &mut dest_oci,
- &mut new_manifest,
- &mut new_config,
- &mut labels,
- chunking,
- &opts,
- "",
- )?;
+ let mut dest_oci = ocidir::OciDir::ensure(dest_oci)?;
+
+ let commit_chunk_ref = commit_layer
+ .as_ref()
+ .map(|l| ref_for_layer(l))
+ .transpose()?;
+ let commit_chunk_rev = commit_chunk_ref
+ .as_ref()
+ .map(|r| repo.require_rev(&r))
+ .transpose()?;
+ if let Some(commit_chunk_rev) = commit_chunk_rev {
+ let mut chunking = chunking::Chunking::new(repo, &commit_chunk_rev)?;
+ for layer in component_layers {
+ chunking_from_layer_committed(repo, layer, &mut chunking)?;
+ }
+
+ // Given the object chunking information we recomputed from what
+ // we found on disk, re-serialize to layers (tarballs).
+ export_chunked(
+ repo,
+ &srcinfo.base_commit,
+ &mut dest_oci,
+ &mut new_manifest,
+ &mut new_config,
+ &mut labels,
+ chunking,
+ &opts,
+ "",
+ )?;
+ }
// Now, handle the non-ostree layers; this is a simple conversion of
//
I tried /usr/libexec/bootc-base-imagectl rechunk on custom image, the chunked image does not have final-diffid issue when run bootc image copy-to-storage.
Does that mean custom image need rechunk? Thanks.