Skip to content
Draft
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
795 changes: 397 additions & 398 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ clap_mangen = { version = "0.3.0" }
# [patch."https://github.com/composefs/composefs-rs"]
# cfsctl = { path = "/path/to/composefs-rs/crates/cfsctl" }
# The Justfile will auto-detect these and bind-mount them into container builds.
cfsctl = { git = "https://github.com/composefs/composefs-rs", rev = "2203e8f", package = "cfsctl", features = ["rhel9"] }
cfsctl = { git = "https://github.com/composefs/composefs-rs", rev = "749466a", package = "cfsctl", features = ["rhel9"] }
fn-error-context = "0.2.1"
hex = "0.4.3"
indicatif = "0.18.0"
Expand Down
4 changes: 3 additions & 1 deletion crates/initramfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,9 @@ pub fn mount_composefs_image(
allow_missing_fsverity: bool,
) -> Result<OwnedFd> {
let mut repo = Repository::<Sha512HashValue>::open_path(sysroot, "composefs")?;
repo.set_insecure(allow_missing_fsverity);
if allow_missing_fsverity {
repo.set_insecure();
}
let rootfs = repo
.mount(name)
.context("Failed to mount composefs image")?;
Expand Down
11 changes: 7 additions & 4 deletions crates/lib/src/bootc_composefs/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ use composefs_boot::bootloader::{
UsrLibModulesVmlinuz,
};
use composefs_boot::{cmdline::get_cmdline_composefs, os_release::OsReleaseInfo, uki};
use composefs_oci::OciDigest;
use composefs_oci::image::create_filesystem as create_composefs_filesystem;
use fn_error_context::context;
use rustix::{mount::MountFlags, path::Arg};
Expand Down Expand Up @@ -1257,23 +1258,25 @@ fn get_secureboot_keys(fs: &Dir, p: &str) -> Result<Option<SecurebootKeys>> {
pub(crate) async fn setup_composefs_boot(
root_setup: &RootSetup,
state: &State,
image_id: &str,
config_digest: &OciDigest,
allow_missing_fsverity: bool,
) -> Result<()> {
const COMPOSEFS_BOOT_SETUP_JOURNAL_ID: &str = "1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5";

tracing::info!(
message_id = COMPOSEFS_BOOT_SETUP_JOURNAL_ID,
bootc.operation = "boot_setup",
bootc.image_id = image_id,
bootc.config_digest = %config_digest,
bootc.allow_missing_fsverity = allow_missing_fsverity,
"Setting up composefs boot",
);

let mut repo = open_composefs_repo(&root_setup.physical_root)?;
repo.set_insecure(allow_missing_fsverity);
if allow_missing_fsverity {
repo.set_insecure();
}

let mut fs = create_composefs_filesystem(&repo, image_id, None)?;
let mut fs = create_composefs_filesystem(&repo, config_digest, None)?;
let entries = fs.transform_for_boot(&repo)?;
let id = fs.commit_image(&repo, None)?;
let mounted_fs = Dir::reopen_dir(
Expand Down
12 changes: 8 additions & 4 deletions crates/lib/src/bootc_composefs/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ pub(crate) fn new_temp_composefs_repo() -> Result<(TempDir, Arc<ComposefsReposit
let td_path = td_guard.path();
let td_dir = Dir::open_ambient_dir(td_path, cap_std::ambient_authority())?;

td_dir.create_dir("repo")?;
let repo_dir = td_dir.open_dir("repo")?;
let mut repo = ComposefsRepository::open_path(&repo_dir, ".").context("Init cfs repo")?;
let (mut repo, _) = ComposefsRepository::init_path(
&td_dir,
"repo",
composefs::fsverity::Algorithm::SHA512,
false,
)
.context("Init cfs repo")?;
// We don't need to hard require verity on the *host* system, we're just computing a checksum here
repo.set_insecure(true);
repo.set_insecure();
Ok((td_guard, Arc::new(repo)))
}

Expand Down
5 changes: 2 additions & 3 deletions crates/lib/src/bootc_composefs/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ pub async fn export_repo_to_image(

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

// We want the digest in the form of "sha256:abc123"
let config_digest = format!("{}", imginfo.manifest.config().digest());
let config_digest = imginfo.manifest.config().digest();

let var_tmp =
Dir::open_ambient_dir("/var/tmp", ambient_authority()).context("Opening /var/tmp")?;
Expand All @@ -56,7 +55,7 @@ pub async fn export_repo_to_image(

// Use composefs_oci::open_config to get the config and layer map
let (config, layer_map) =
open_config(&*booted_cfs.repo, &config_digest, None).context("Opening config")?;
open_config(&*booted_cfs.repo, config_digest, None).context("Opening config")?;

// We can't guarantee that we'll get the same tar stream as the container image
// So we create new config and manifest
Expand Down
29 changes: 24 additions & 5 deletions crates/lib/src/bootc_composefs/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ pub(crate) fn open_composefs_repo(rootfs_dir: &Dir) -> Result<crate::store::Comp
.context("Failed to open composefs repository")
}

/// Initialize (or idempotently re-open) a composefs repository.
/// Used during install when the repo may not exist yet.
pub(crate) fn init_composefs_repo(rootfs_dir: &Dir) -> Result<crate::store::ComposefsRepository> {
let (repo, _created) = crate::store::ComposefsRepository::init_path(
rootfs_dir,
"composefs",
composefs::fsverity::Algorithm::SHA512,
false,
)
.context("Failed to initialize composefs repository")?;
Ok(repo)
}

pub(crate) async fn initialize_composefs_repository(
state: &State,
root_setup: &RootSetup,
Expand All @@ -47,8 +60,10 @@ pub(crate) async fn initialize_composefs_repository(

crate::store::ensure_composefs_dir(rootfs_dir)?;

let mut repo = open_composefs_repo(rootfs_dir)?;
repo.set_insecure(allow_missing_fsverity);
let mut repo = init_composefs_repo(rootfs_dir)?;
if allow_missing_fsverity {
repo.set_insecure();
}

let OstreeExtImgRef {
name: image_name,
Expand Down Expand Up @@ -117,7 +132,9 @@ pub(crate) async fn pull_composefs_repo(
let rootfs_dir = Dir::open_ambient_dir("/sysroot", ambient_authority())?;

let mut repo = open_composefs_repo(&rootfs_dir).context("Opening composefs repo")?;
repo.set_insecure(allow_missing_fsverity);
if allow_missing_fsverity {
repo.set_insecure();
}

let final_imgref = get_imgref(transport, image);

Expand All @@ -132,13 +149,15 @@ pub(crate) async fn pull_composefs_repo(

tracing::info!(
message_id = COMPOSEFS_PULL_JOURNAL_ID,
id = pull_result.config_digest,
id = %pull_result.config_digest,
verity = pull_result.config_verity.to_hex(),
"Pulled image into repository"
);

let mut repo = open_composefs_repo(&rootfs_dir)?;
repo.set_insecure(allow_missing_fsverity);
if allow_missing_fsverity {
repo.set_insecure();
}

let mut fs: crate::store::ComposefsFilesystem =
create_composefs_filesystem(&repo, &pull_result.config_digest, None)
Expand Down
2 changes: 1 addition & 1 deletion crates/lib/src/bootc_composefs/switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub(crate) async fn switch_composefs(
storage,
booted_cfs,
&host,
img_config.manifest.config().digest().digest(),
img_config.manifest.config().digest(),
&cfg_verity,
true,
)?;
Expand Down
16 changes: 9 additions & 7 deletions crates/lib/src/bootc_composefs/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use cfsctl::composefs_boot;
use cfsctl::composefs_oci;
use composefs::fsverity::{FsVerityHashValue, Sha512HashValue};
use composefs_boot::BootOps;
use composefs_oci::OciDigest;
use composefs_oci::image::create_filesystem;
use fn_error_context::context;
use ocidir::cap_std::ambient_authority;
Expand Down Expand Up @@ -59,10 +60,10 @@ pub(crate) async fn is_image_pulled(
let imgref_repr = get_imgref(&imgref.transport, &imgref.image);
let img_config_manifest = get_container_manifest_and_config(&imgref_repr).await?;

let img_digest = img_config_manifest.manifest.config().digest().digest();
let config_digest = img_config_manifest.manifest.config().digest();

// TODO: export config_identifier function from composefs-oci/src/lib.rs and use it here
let img_id = format!("oci-config-sha256:{img_digest}");
let img_id = format!("oci-config-{config_digest}");

// NB: add deep checking?
let container_pulled = repo.has_stream(&img_id).context("Checking stream")?;
Expand Down Expand Up @@ -132,13 +133,13 @@ pub(crate) fn validate_update(
storage: &Storage,
booted_cfs: &BootedComposefs,
host: &Host,
img_digest: &str,
config_digest: &OciDigest,
config_verity: &Sha512HashValue,
is_switch: bool,
) -> Result<UpdateAction> {
let repo = &*booted_cfs.repo;

let mut fs = create_filesystem(repo, img_digest, Some(config_verity))?;
let mut fs = create_filesystem(repo, config_digest, Some(config_verity))?;
fs.transform_for_boot(&repo)?;

let image_id = fs.compute_image_id();
Expand Down Expand Up @@ -409,7 +410,8 @@ pub(crate) async fn upgrade_composefs(
let repo = &*composefs.repo;

let (img_pulled, mut img_config) = is_image_pulled(&repo, booted_imgref).await?;
let booted_img_digest = img_config.manifest.config().digest().digest().to_owned();
let booted_config_digest = img_config.manifest.config().digest().clone();
let booted_img_digest = booted_config_digest.to_string();

// Check if we already have this update staged
// Or if we have another staged deployment with a different image
Expand Down Expand Up @@ -441,7 +443,7 @@ pub(crate) async fn upgrade_composefs(
storage,
composefs,
&host,
img_config.manifest.config().digest().digest(),
img_config.manifest.config().digest(),
&cfg_verity,
false,
)?;
Expand Down Expand Up @@ -477,7 +479,7 @@ pub(crate) async fn upgrade_composefs(
storage,
composefs,
&host,
&booted_img_digest,
&booted_config_digest,
&cfg_verity,
false,
)?;
Expand Down
12 changes: 8 additions & 4 deletions crates/lib/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl BootedStorage {
let (physical_root, run) = get_physical_root_and_run()?;
let mut composefs = ComposefsRepository::open_path(&physical_root, COMPOSEFS)?;
if cmdline.allow_missing_fsverity {
composefs.set_insecure(true);
composefs.set_insecure();
}
let composefs = Arc::new(composefs);

Expand Down Expand Up @@ -471,11 +471,15 @@ impl Storage {
let ostree = self.get_ostree()?;
let ostree_repo = &ostree.repo();
let ostree_verity = ostree_ext::fsverity::is_verity_enabled(ostree_repo)?;
let mut composefs =
ComposefsRepository::open_path(self.physical_root.open_dir(COMPOSEFS)?, ".")?;
let (mut composefs, _) = ComposefsRepository::init_path(
&self.physical_root,
COMPOSEFS,
composefs::fsverity::Algorithm::SHA512,
false,
)?;
if !ostree_verity.enabled {
tracing::debug!("Setting insecure mode for composefs repo");
composefs.set_insecure(true);
composefs.set_insecure();
}
let composefs = Arc::new(composefs);
let r = Arc::clone(self.composefs.get_or_init(|| composefs));
Expand Down
Loading