Skip to content
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
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ chrono = { version = "0.4.38", default-features = false }
clap = "4.5.4"
clap_mangen = { version = "0.2.20" }
# Reviewers (including AI tools): This hash is duplicated as there's not a much better way to handle it right now
composefs = { git = "https://github.com/containers/composefs-rs", rev = "82e211ee3e5c8e2b7b3bc00b40b828133633c41b", package = "composefs", features = ["rhel9"] }
composefs-boot = { git = "https://github.com/containers/composefs-rs", rev = "82e211ee3e5c8e2b7b3bc00b40b828133633c41b", package = "composefs-boot" }
composefs-oci = { git = "https://github.com/containers/composefs-rs", rev = "82e211ee3e5c8e2b7b3bc00b40b828133633c41b", package = "composefs-oci" }
composefs = { git = "https://github.com/containers/composefs-rs", rev = "0f636031a1ec81cdd9e7f674909ef6b75c2642cb", package = "composefs", features = ["rhel9"] }
composefs-boot = { git = "https://github.com/containers/composefs-rs", rev = "0f636031a1ec81cdd9e7f674909ef6b75c2642cb", package = "composefs-boot" }
composefs-oci = { git = "https://github.com/containers/composefs-rs", rev = "0f636031a1ec81cdd9e7f674909ef6b75c2642cb", package = "composefs-oci" }
fn-error-context = "0.2.1"
hex = "0.4.3"
indicatif = "0.18.0"
Expand Down
68 changes: 35 additions & 33 deletions crates/lib/src/bootc_composefs/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const SYSTEMD_LOADER_CONF_PATH: &str = "loader/loader.conf";
/// directory specified by the BLS spec. We do this because we want systemd-boot to only look at
/// our config files and not show the actual UKIs in the bootloader menu
/// This is relative to the ESP
const SYSTEMD_UKI_DIR: &str = "EFI/Linux/bootc";
pub(crate) const SYSTEMD_UKI_DIR: &str = "EFI/Linux/bootc";

pub(crate) enum BootSetupType<'a> {
/// For initial setup, i.e. install to-disk
Expand Down Expand Up @@ -211,9 +211,9 @@ fn compute_boot_digest(
/// Given the SHA256 sum of current VMlinuz + Initrd combo, find boot entry with the same SHA256Sum
///
/// # Returns
/// Returns the verity of the deployment that has a boot digest same as the one passed in
/// Returns the verity of all deployments that have a boot digest same as the one passed in
#[context("Checking boot entry duplicates")]
fn find_vmlinuz_initrd_duplicates(digest: &str) -> Result<Option<String>> {
pub(crate) fn find_vmlinuz_initrd_duplicates(digest: &str) -> Result<Option<Vec<String>>> {
let deployments = Dir::open_ambient_dir(STATE_DIR_ABS, ambient_authority());

let deployments = match deployments {
Expand All @@ -223,7 +223,7 @@ fn find_vmlinuz_initrd_duplicates(digest: &str) -> Result<Option<String>> {
Err(e) => anyhow::bail!(e),
};

let mut symlink_to: Option<String> = None;
let mut symlink_to: Option<Vec<String>> = None;

for depl in deployments.entries()? {
let depl = depl?;
Expand All @@ -243,8 +243,10 @@ fn find_vmlinuz_initrd_duplicates(digest: &str) -> Result<Option<String>> {
match ini.get::<String>(ORIGIN_KEY_BOOT, ORIGIN_KEY_BOOT_DIGEST) {
Some(hash) => {
if hash == digest {
symlink_to = Some(depl_file_name.to_string());
break;
match symlink_to {
Some(ref mut prev) => prev.push(depl_file_name.to_string()),
None => symlink_to = Some(vec![depl_file_name.to_string()]),
}
}
}

Expand Down Expand Up @@ -479,6 +481,8 @@ pub(crate) fn setup_composefs_bls_boot(

match find_vmlinuz_initrd_duplicates(&boot_digest)? {
Some(symlink_to) => {
let symlink_to = &symlink_to[0];

match bls_config.cfg_type {
BLSConfigType::NonEFI {
ref mut linux,
Expand Down Expand Up @@ -692,28 +696,27 @@ fn write_grub_uki_menuentry(
//
// TODO: We might find a staged deployment here
if is_upgrade {
let mut buffer = vec![];

// Shouldn't really fail so no context here
buffer.write_all(efi_uuid_source.as_bytes())?;
buffer.write_all(
MenuEntry::new(&boot_label, &id.to_hex())
.to_string()
.as_bytes(),
)?;

let mut str_buf = String::new();
let boot_dir =
Dir::open_ambient_dir(boot_dir, ambient_authority()).context("Opening boot dir")?;
let entries = get_sorted_grub_uki_boot_entries(&boot_dir, &mut str_buf)?;

// Write out only the currently booted entry, which should be the very first one
// Even if we have booted into the second menuentry "boot entry", the default will be the
// first one
buffer.write_all(entries[0].to_string().as_bytes())?;

grub_dir
.atomic_write(user_cfg_name, buffer)
.atomic_replace_with(user_cfg_name, |f| -> std::io::Result<_> {
f.write_all(efi_uuid_source.as_bytes())?;
f.write_all(
MenuEntry::new(&boot_label, &id.to_hex())
.to_string()
.as_bytes(),
)?;

// Write out only the currently booted entry, which should be the very first one
// Even if we have booted into the second menuentry "boot entry", the default will be the
// first one
f.write_all(entries[0].to_string().as_bytes())?;

Ok(())
})
.with_context(|| format!("Writing to {user_cfg_name}"))?;

rustix::fs::fsync(grub_dir.reopen_as_ownedfd()?).context("fsync")?;
Expand All @@ -733,18 +736,17 @@ fn write_grub_uki_menuentry(
)?;

// Write to grub2/user.cfg
let mut buffer = vec![];

// Shouldn't really fail so no context here
buffer.write_all(efi_uuid_source.as_bytes())?;
buffer.write_all(
MenuEntry::new(&boot_label, &id.to_hex())
.to_string()
.as_bytes(),
)?;

grub_dir
.atomic_write(user_cfg_name, buffer)
.atomic_replace_with(user_cfg_name, |f| -> std::io::Result<_> {
f.write_all(efi_uuid_source.as_bytes())?;
f.write_all(
MenuEntry::new(&boot_label, &id.to_hex())
.to_string()
.as_bytes(),
)?;

Ok(())
})
.with_context(|| format!("Writing to {user_cfg_name}"))?;

rustix::fs::fsync(grub_dir.reopen_as_ownedfd()?).context("fsync")?;
Expand Down
Loading