Skip to content

Commit 561dd37

Browse files
various: adjust to composefs-rs changes
This is mostly about the new splitstream API, but it also adopts the new library API exposed by the `cfsctl` crate, removing our private copy. Co-authored-by: Colin Walters <[email protected]> Assisted-by: Claude Code (Sonnet 4)
1 parent fd7f1b6 commit 561dd37

File tree

9 files changed

+236
-594
lines changed

9 files changed

+236
-594
lines changed

Cargo.lock

Lines changed: 204 additions & 178 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ chrono = { version = "0.4.38", default-features = false }
4141
clap = "4.5.4"
4242
clap_mangen = { version = "0.2.20" }
4343
# Reviewers (including AI tools): This hash is duplicated as there's not a much better way to handle it right now
44-
composefs = { git = "https://github.com/containers/composefs-rs", rev = "1498349e11d0e4bd545feab533f0b7ab5294ae9a", package = "composefs", features = ["rhel9"] }
45-
composefs-boot = { git = "https://github.com/containers/composefs-rs", rev = "1498349e11d0e4bd545feab533f0b7ab5294ae9a", package = "composefs-boot" }
46-
composefs-oci = { git = "https://github.com/containers/composefs-rs", rev = "1498349e11d0e4bd545feab533f0b7ab5294ae9a", package = "composefs-oci" }
44+
composefs = { git = "https://github.com/containers/composefs-rs", rev = "c3677f1a3599be0015db6798b60c5bdfa3e43d7e", package = "composefs", features = ["rhel9"] }
45+
composefs-boot = { git = "https://github.com/containers/composefs-rs", rev = "c3677f1a3599be0015db6798b60c5bdfa3e43d7e", package = "composefs-boot" }
46+
composefs-oci = { git = "https://github.com/containers/composefs-rs", rev = "c3677f1a3599be0015db6798b60c5bdfa3e43d7e", package = "composefs-oci" }
4747
fn-error-context = "0.2.1"
4848
hex = "0.4.3"
4949
indicatif = "0.18.0"

crates/lib/src/bootc_composefs/export.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ use std::{fs::File, os::fd::AsRawFd};
33
use anyhow::{Context, Result};
44
use cap_std_ext::cap_std::{ambient_authority, fs::Dir};
55
use composefs::splitstream::SplitStreamData;
6+
use composefs_oci::open_config;
67
use ocidir::{oci_spec::image::Platform, OciDir};
78
use ostree_ext::container::skopeo;
8-
use ostree_ext::{container::Transport, oci_spec::image::ImageConfiguration};
9+
use ostree_ext::container::Transport;
910
use tar::EntryType;
1011

1112
use crate::image::get_imgrefs_for_copy;
1213
use crate::{
13-
bootc_composefs::{
14-
status::{get_composefs_status, get_imginfo},
15-
update::str_to_sha256digest,
16-
},
14+
bootc_composefs::status::{get_composefs_status, get_imginfo},
1715
store::{BootedComposefs, Storage},
1816
};
1917

@@ -52,21 +50,17 @@ pub async fn export_repo_to_image(
5250

5351
let imginfo = get_imginfo(storage, &depl_verity, None).await?;
5452

55-
let config_name = &imginfo.manifest.config().digest().digest();
56-
let config_name = str_to_sha256digest(config_name)?;
53+
let config_digest = imginfo.manifest.config().digest().digest();
5754

5855
let var_tmp =
5956
Dir::open_ambient_dir("/var/tmp", ambient_authority()).context("Opening /var/tmp")?;
6057

6158
let tmpdir = cap_std_ext::cap_tempfile::tempdir_in(&var_tmp)?;
6259
let oci_dir = OciDir::ensure(tmpdir.try_clone()?).context("Opening OCI")?;
6360

64-
let mut config_stream = booted_cfs
65-
.repo
66-
.open_stream(&hex::encode(config_name), None)
67-
.context("Opening config stream")?;
68-
69-
let config = ImageConfiguration::from_reader(&mut config_stream)?;
61+
// Use composefs_oci::open_config to get the config and layer map
62+
let (config, layer_map) = open_config(&*booted_cfs.repo, config_digest, None)
63+
.context("Opening config")?;
7064

7165
// We can't guarantee that we'll get the same tar stream as the container image
7266
// So we create new config and manifest
@@ -82,12 +76,14 @@ pub async fn export_repo_to_image(
8276
let total_layers = config.rootfs().diff_ids().len();
8377

8478
for (idx, old_diff_id) in config.rootfs().diff_ids().iter().enumerate() {
85-
let layer_sha256 = str_to_sha256digest(old_diff_id)?;
86-
let layer_verity = config_stream.lookup(&layer_sha256)?;
79+
// Look up the layer verity from the map
80+
let layer_verity = layer_map
81+
.get(old_diff_id.as_str())
82+
.ok_or_else(|| anyhow::anyhow!("Layer {old_diff_id} not found in config"))?;
8783

8884
let mut layer_stream = booted_cfs
8985
.repo
90-
.open_stream(&hex::encode(layer_sha256), Some(layer_verity))?;
86+
.open_stream("", Some(layer_verity), None)?;
9187

9288
let mut layer_writer = oci_dir.create_layer(None)?;
9389
layer_writer.follow_symlinks(false);
@@ -120,7 +116,7 @@ pub async fn export_repo_to_image(
120116

121117
let size = header.entry_size()?;
122118

123-
match layer_stream.read_exact(size as usize, ((size + 511) & !511) as usize)? {
119+
match layer_stream.read_exact(size as usize, ((size as usize) + 511) & !511)? {
124120
SplitStreamData::External(obj_id) => match header.entry_type() {
125121
EntryType::Regular | EntryType::Continuous => {
126122
let file = File::from(booted_cfs.repo.open_object(&obj_id)?);

crates/lib/src/bootc_composefs/repo.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ use std::sync::Arc;
33

44
use anyhow::{Context, Result};
55

6-
use ostree_ext::composefs::{
7-
fsverity::{FsVerityHashValue, Sha512HashValue},
8-
util::Sha256Digest,
9-
};
6+
use ostree_ext::composefs::fsverity::{FsVerityHashValue, Sha512HashValue};
107
use ostree_ext::composefs_boot::{bootloader::BootEntry as ComposefsBootEntry, BootOps};
118
use ostree_ext::composefs_oci::{
129
image::create_filesystem as create_composefs_filesystem, pull as composefs_oci_pull,
@@ -26,7 +23,7 @@ pub(crate) fn open_composefs_repo(rootfs_dir: &Dir) -> Result<crate::store::Comp
2623
pub(crate) async fn initialize_composefs_repository(
2724
state: &State,
2825
root_setup: &RootSetup,
29-
) -> Result<(Sha256Digest, impl FsVerityHashValue)> {
26+
) -> Result<(String, impl FsVerityHashValue)> {
3027
let rootfs_dir = &root_setup.physical_root;
3128

3229
rootfs_dir
@@ -94,11 +91,11 @@ pub(crate) async fn pull_composefs_repo(
9491
.await
9592
.context("Pulling composefs repo")?;
9693

97-
tracing::info!("ID: {}, Verity: {}", hex::encode(id), verity.to_hex());
94+
tracing::info!("ID: {id}, Verity: {}", verity.to_hex());
9895

9996
let repo = open_composefs_repo(&rootfs_dir)?;
10097
let mut fs: crate::store::ComposefsFilesystem =
101-
create_composefs_filesystem(&repo, &hex::encode(id), None)
98+
create_composefs_filesystem(&repo, &id, None)
10299
.context("Failed to create composefs filesystem")?;
103100

104101
let entries = fs.transform_for_boot(&repo)?;

crates/lib/src/bootc_composefs/update.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use camino::Utf8PathBuf;
33
use cap_std_ext::cap_std::fs::Dir;
44
use composefs::{
55
fsverity::{FsVerityHashValue, Sha512HashValue},
6-
util::{parse_sha256, Sha256Digest},
76
};
87
use composefs_boot::BootOps;
98
use composefs_oci::image::create_filesystem;
@@ -28,12 +27,6 @@ use crate::{
2827
store::{BootedComposefs, ComposefsRepository, Storage},
2928
};
3029

31-
#[context("Getting SHA256 Digest for {id}")]
32-
pub fn str_to_sha256digest(id: &str) -> Result<Sha256Digest> {
33-
let id = id.strip_prefix("sha256:").unwrap_or(id);
34-
Ok(parse_sha256(&id)?)
35-
}
36-
3730
/// Checks if a container image has been pulled to the local composefs repository.
3831
///
3932
/// This function verifies whether the specified container image exists in the local
@@ -61,10 +54,9 @@ pub(crate) async fn is_image_pulled(
6154
let img_config_manifest = get_container_manifest_and_config(&imgref_repr).await?;
6255

6356
let img_digest = img_config_manifest.manifest.config().digest().digest();
64-
let img_sha256 = str_to_sha256digest(&img_digest)?;
6557

66-
// check_stream is expensive to run, but probably a good idea
67-
let container_pulled = repo.check_stream(&img_sha256).context("Checking stream")?;
58+
// NB: add deep checking?
59+
let container_pulled = repo.has_stream(img_digest).context("Checking stream")?;
6860

6961
Ok((container_pulled, img_config_manifest))
7062
}

0 commit comments

Comments
 (0)