Skip to content
Open
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
240 changes: 233 additions & 7 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"]
# composefs-ctl = { path = "/path/to/composefs-rs/crates/composefs-ctl" }
# The Justfile will auto-detect these and bind-mount them into container builds.
composefs-ctl = { git = "https://github.com/composefs/composefs-rs", rev = "e2770757762ec5091bb183bf0e778fe97c8d5694" }
composefs-ctl = { git = "https://github.com/composefs/composefs-rs", rev = "a4c1ca7a7a5e8cc5b87bec3ca212c2b77f48f4f5" }
fn-error-context = "0.2.1"
futures-util = "0.3"
hex = "0.4.3"
Expand Down
1 change: 1 addition & 0 deletions crates/etc-merge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl From<(&cap_std::fs::Metadata, Xattrs)> for MyStat {
st_uid: value.0.uid(),
st_gid: value.0.gid(),
st_mtim_sec: value.0.mtime(),
st_mtim_nsec: value.0.mtime_nsec() as u32,
xattrs: value.1,
})
}
Expand Down
19 changes: 14 additions & 5 deletions crates/initramfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use composefs::{
mountcompat::{overlayfs_set_fd, overlayfs_set_lower_and_data_fds, prepare_mount},
repository::Repository,
};
use composefs_boot::cmdline::get_cmdline_composefs;
use composefs_boot::cmdline::ComposefsCmdline;
use composefs_ctl::composefs;
use composefs_ctl::composefs_boot;

Expand Down Expand Up @@ -463,11 +463,17 @@ pub fn setup_root(args: Args) -> Result<()> {
config
};

let (image, insecure) = get_cmdline_composefs::<Sha512HashValue>(&cmdline)?;
let composefs_info = ComposefsCmdline::<Sha512HashValue>::from_cmdline(&cmdline)
.context("Failed to parse composefs cmdline")?
.ok_or_else(|| anyhow::anyhow!("No composefs image in cmdline"))?;

let new_root = match &args.root_fs {
Some(path) => open_root_fs(path).context("Failed to clone specified root fs")?,
None => mount_composefs_image(&sysroot, &image.to_hex(), insecure)?,
None => mount_composefs_image(
&sysroot,
&composefs_info.digest().to_hex(),
composefs_info.is_insecure(),
)?,
};

// we need to clone this before the next step to make sure we get the old one
Expand Down Expand Up @@ -497,7 +503,7 @@ pub fn setup_root(args: Args) -> Result<()> {
let transient_overlay_fd: Option<OwnedFd> = if config.root.transient {
let overlay_fd = overlay_transient(
&new_root,
&format!("transient:composefs={}", image.to_hex()),
&format!("transient:composefs={}", composefs_info.digest().to_hex()),
None,
)?;

Expand Down Expand Up @@ -533,7 +539,10 @@ pub fn setup_root(args: Args) -> Result<()> {
}

// etc + var
let state = open_dir(open_dir(&sysroot, "state/deploy")?, image.to_hex())?;
let state = open_dir(
open_dir(&sysroot, "state/deploy")?,
composefs_info.digest().to_hex(),
)?;
mount_subdir(visible_root, &state, "etc", config.etc, MountType::Bind)?;
// /var is bind-mounted from the deployment state directory by default.
// The systemd.volatile=state cmdline detection above (or an explicit
Expand Down
13 changes: 9 additions & 4 deletions crates/lib/src/bootc_composefs/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ use composefs_boot::bootloader::{
BootEntry as ComposefsBootEntry, EFI_ADDON_DIR_EXT, EFI_ADDON_FILE_EXT, EFI_EXT, PEType,
UsrLibModulesVmlinuz, get_boot_resources,
};
use composefs_boot::{cmdline::get_cmdline_composefs, os_release::OsReleaseInfo, uki};
use composefs_boot::{
cmdline::ComposefsCmdline as ComposefsBootCmdline, os_release::OsReleaseInfo, uki,
};
use composefs_ctl::composefs;
use composefs_ctl::composefs_boot;
use composefs_ctl::composefs_oci;
Expand Down Expand Up @@ -811,8 +813,11 @@ fn write_pe_to_esp(
if matches!(pe_type, PEType::Uki) {
let cmdline = uki::get_cmdline_buffered(&mut uki_reader).context("Getting UKI cmdline")?;

let (composefs_cmdline, missing_verity_allowed_cmdline) =
get_cmdline_composefs::<Sha512HashValue>(&cmdline).context("Parsing composefs=")?;
let composefs_info = ComposefsBootCmdline::<Sha512HashValue>::from_cmdline(&cmdline)
.context("Parsing composefs=")?
.ok_or_else(|| anyhow::anyhow!("No composefs image in UKI cmdline"))?;
let composefs_cmdline = composefs_info.digest();
let missing_verity_allowed_cmdline = composefs_info.is_insecure();

// If the UKI cmdline does not match what the user has passed as cmdline option
// NOTE: This will only be checked for new installs and now upgrades/switches
Expand All @@ -830,7 +835,7 @@ fn write_pe_to_esp(
_ => { /* no-op */ }
}

if composefs_cmdline != *uki_id {
if *composefs_cmdline != *uki_id {
anyhow::bail!(
"The UKI has the wrong composefs= parameter (is '{composefs_cmdline:?}', should be {uki_id:?})"
);
Expand Down
10 changes: 5 additions & 5 deletions crates/lib/src/bootc_composefs/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use cap_std_ext::cap_std;
use cap_std_ext::cap_std::fs::Dir;
use composefs::dumpfile;
use composefs::fsverity::{Algorithm, FsVerityHashValue};
use composefs::repository::RepositoryConfig;
use composefs_boot::BootOps as _;
use composefs_ctl::composefs;
use composefs_ctl::composefs_boot;
Expand All @@ -30,11 +31,10 @@ pub(crate) fn new_temp_composefs_repo() -> Result<(TempDir, Arc<ComposefsReposit

td_dir.create_dir("repo")?;
let repo_dir = td_dir.open_dir("repo")?;
let (mut repo, _created) =
ComposefsRepository::init_path(&repo_dir, ".", 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();
let config = RepositoryConfig::new(Algorithm::SHA512).set_insecure();
let (repo, _created) =
ComposefsRepository::init_path(&repo_dir, ".", config).context("Init cfs repo")?;
Ok((td_guard, Arc::new(repo)))
}

Expand Down Expand Up @@ -81,7 +81,7 @@ pub(crate) async fn compute_composefs_digest(
.await
.context("Reading container root")?;
fs.transform_for_boot(&repo).context("Preparing for boot")?;
let id = fs.compute_image_id();
let id = fs.compute_image_id(repo.erofs_version());
let digest = id.to_hex();

if let Some(dumpfile_path) = write_dumpfile_to {
Expand Down
2 changes: 1 addition & 1 deletion crates/lib/src/bootc_composefs/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ pub(crate) async fn composefs_gc(
ref_digest,
None,
) {
if let Some(img_ref) = img.image_ref() {
if let Some(img_ref) = img.image_ref(booted_cfs.repo.erofs_version()) {
if img_ref.to_hex() == *verity {
tracing::info!(
"Deployment {verity} has no manifest_digest in origin; \
Expand Down
20 changes: 10 additions & 10 deletions crates/lib/src/bootc_composefs/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use std::sync::Arc;
use anyhow::{Context, Result};

use composefs::fsverity::{FsVerityHashValue, Sha512HashValue};
use composefs::repository::RepositoryConfig;
use composefs_boot::bootloader::{BootEntry as ComposefsBootEntry, get_boot_resources};
use composefs_ctl::composefs;
use composefs_ctl::composefs_boot;
Expand Down Expand Up @@ -99,16 +100,15 @@ pub(crate) async fn initialize_composefs_repository(

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

let (mut repo, _created) = crate::store::ComposefsRepository::init_path(
rootfs_dir,
"composefs",
composefs::fsverity::Algorithm::SHA512,
!allow_missing_fsverity,
)
.context("Failed to initialize composefs repository")?;
if allow_missing_fsverity {
repo.set_insecure();
}
let config = RepositoryConfig::new(composefs::fsverity::Algorithm::SHA512);
let config = if allow_missing_fsverity {
config.set_insecure()
} else {
config
};
let (repo, _created) =
crate::store::ComposefsRepository::init_path(rootfs_dir, "composefs", config)
.context("Failed to initialize composefs repository")?;

let imgref: containers_image_proxy::ImageReference = state
.source
Expand Down
2 changes: 1 addition & 1 deletion crates/lib/src/bootc_composefs/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub(crate) fn validate_update(
let mut fs = create_filesystem(repo, &oci_digest, Some(config_verity))?;
fs.transform_for_boot(&repo)?;

let image_id = fs.compute_image_id();
let image_id = fs.compute_image_id(repo.erofs_version());

let all_deployments = host.all_composefs_deployments()?;

Expand Down
2 changes: 1 addition & 1 deletion crates/lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1892,7 +1892,7 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
)
.context("Populating fs")?;
fs.transform_for_boot(&repo).context("Preparing for boot")?;
let id = fs.compute_image_id();
let id = fs.compute_image_id(repo.erofs_version());
println!("{}", id.to_hex());

if let Some(path) = write_dumpfile_to.as_deref() {
Expand Down
7 changes: 5 additions & 2 deletions crates/lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ use crate::task::Task;
use crate::utils::sigpolicy_from_opt;
use bootc_kernel_cmdline::{INITRD_ARG_PREFIX, ROOTFLAGS, bytes, utf8};
use bootc_mount::Filesystem;
use composefs_ctl::composefs::repository::RepositoryConfig;

/// The toplevel boot directory
pub(crate) const BOOT: &str = "boot";
Expand Down Expand Up @@ -2020,11 +2021,13 @@ async fn install_to_filesystem_impl(
let img_manifest_config = get_container_manifest_and_config(&imgref).await?;
crate::store::ensure_composefs_dir(&rootfs.physical_root)?;
// Use init_path since the repo may not exist yet during install
let config =
RepositoryConfig::new(composefs_ctl::composefs::fsverity::Algorithm::SHA512)
.set_insecure();
let (cfs_repo, _created) = crate::store::ComposefsRepository::init_path(
&rootfs.physical_root,
crate::store::COMPOSEFS,
composefs_ctl::composefs::fsverity::Algorithm::SHA512,
false,
config,
)?;
crate::deploy::check_disk_space_composefs(
&cfs_repo,
Expand Down
19 changes: 9 additions & 10 deletions crates/lib/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ use ostree_ext::{gio, ostree};
use rustix::fs::Mode;

use composefs::fsverity::Sha512HashValue;
use composefs::repository::RepositoryConfig;
use composefs_ctl::composefs;

use crate::bootc_composefs::backwards_compat::bcompat_boot::prepend_custom_prefix;
Expand Down Expand Up @@ -618,16 +619,14 @@ 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, _created) = ComposefsRepository::init_path(
self.physical_root.open_dir(COMPOSEFS)?,
".",
composefs::fsverity::Algorithm::SHA512,
ostree_verity.enabled,
)?;
if !ostree_verity.enabled {
tracing::debug!("Setting insecure mode for composefs repo");
composefs.set_insecure();
}
let config = RepositoryConfig::new(composefs::fsverity::Algorithm::SHA512);
let config = if ostree_verity.enabled {
config
} else {
config.set_insecure()
};
let (composefs, _created) =
ComposefsRepository::init_path(self.physical_root.open_dir(COMPOSEFS)?, ".", config)?;
let composefs = Arc::new(composefs);
let r = Arc::clone(self.composefs.get_or_init(|| composefs));
Ok(r)
Expand Down
13 changes: 5 additions & 8 deletions crates/lib/src/testutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use anyhow::{Context, Result};
use cap_std_ext::cap_std::{self, fs::Dir};
use cap_std_ext::cap_tempfile;
use cap_std_ext::dirext::CapStdExtDirExt;
use composefs_ctl::composefs::repository::RepositoryConfig;

use crate::bootc_composefs::boot::{
FILENAME_PRIORITY_PRIMARY, FILENAME_PRIORITY_SECONDARY, get_type1_dir_name, primary_sort_key,
Expand Down Expand Up @@ -164,14 +165,10 @@ impl TestRoot {

// Initialize the composefs repo (creates meta.json)
let repo_dir = root.open_dir("composefs")?;
let (mut repo, _created) = ComposefsRepository::init_path(
&repo_dir,
".",
composefs_ctl::composefs::fsverity::Algorithm::SHA512,
false,
)
.context("Initializing composefs repo")?;
repo.set_insecure();
let config = RepositoryConfig::new(composefs_ctl::composefs::fsverity::Algorithm::SHA512)
.set_insecure();
let (repo, _created) = ComposefsRepository::init_path(&repo_dir, ".", config)
.context("Initializing composefs repo")?;

let mut test_root = Self {
root,
Expand Down