Skip to content

Commit 0e4769c

Browse files
Johan-Liebert1jeckersb
authored andcommitted
composefs-backend/bls: Get title, version from os-release
For Type1 boot entries, get the version and title from /usr/lib/os-release only defaulting to "sort_key" and "verity hash" respectively if we fail to find them in the file. Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent f74462e commit 0e4769c

File tree

2 files changed

+105
-86
lines changed

2 files changed

+105
-86
lines changed

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 104 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ pub fn get_sysroot_parent_dev() -> Result<String> {
142142
return Ok(parent);
143143
}
144144

145+
pub fn type1_entry_conf_file_name(sort_key: impl std::fmt::Display) -> String {
146+
format!("bootc-composefs-{sort_key}.conf")
147+
}
148+
145149
/// Compute SHA256Sum of VMlinuz + Initrd
146150
///
147151
/// # Arguments
@@ -264,6 +268,51 @@ fn write_bls_boot_entries_to_disk(
264268
Ok(())
265269
}
266270

271+
/// Parses /usr/lib/os-release and returns title and version fields
272+
/// # Returns
273+
/// - (title, version)
274+
fn osrel_title_and_version(
275+
fs: &FileSystem<Sha256HashValue>,
276+
repo: &ComposefsRepository<Sha256HashValue>,
277+
) -> Result<Option<(Option<String>, Option<String>)>> {
278+
// Every update should have its own /usr/lib/os-release
279+
let (dir, fname) = fs
280+
.root
281+
.split(OsStr::new("/usr/lib/os-release"))
282+
.context("Getting /usr/lib/os-release")?;
283+
284+
let os_release = dir
285+
.get_file_opt(fname)
286+
.context("Getting /usr/lib/os-release")?;
287+
288+
let Some(os_rel_file) = os_release else {
289+
return Ok(None);
290+
};
291+
292+
let file_contents = match read_file(os_rel_file, repo) {
293+
Ok(c) => c,
294+
Err(e) => {
295+
tracing::warn!("Could not read /usr/lib/os-release: {e:?}");
296+
return Ok(None);
297+
}
298+
};
299+
300+
let file_contents = match std::str::from_utf8(&file_contents) {
301+
Ok(c) => c,
302+
Err(e) => {
303+
tracing::warn!("/usr/lib/os-release did not have valid UTF-8: {e}");
304+
return Ok(None);
305+
}
306+
};
307+
308+
let parsed_contents = OsReleaseInfo::parse(file_contents);
309+
310+
let title = parsed_contents.get_pretty_name();
311+
let version = parsed_contents.get_version();
312+
313+
Ok(Some((title, version)))
314+
}
315+
267316
struct BLSEntryPath<'a> {
268317
/// Where to write vmlinuz/initrd
269318
entries_path: Utf8PathBuf,
@@ -372,51 +421,33 @@ pub(crate) fn setup_composefs_bls_boot(
372421
};
373422

374423
let (bls_config, boot_digest) = match &entry {
375-
ComposefsBootEntry::Type1(..) => unimplemented!(),
376-
ComposefsBootEntry::Type2(..) => unimplemented!(),
424+
ComposefsBootEntry::Type1(..) => anyhow::bail!("Found Type1 entries in /boot"),
425+
ComposefsBootEntry::Type2(..) => anyhow::bail!("Found UKI"),
377426

378427
ComposefsBootEntry::UsrLibModulesVmLinuz(usr_lib_modules_vmlinuz) => {
379428
let boot_digest = compute_boot_digest(usr_lib_modules_vmlinuz, &repo)
380429
.context("Computing boot digest")?;
381430

382-
// Every update should have its own /usr/lib/os-release
383-
let (dir, fname) = fs
384-
.root
385-
.split(OsStr::new("/usr/lib/os-release"))
386-
.context("Getting /usr/lib/os-release")?;
387-
388-
let os_release = dir
389-
.get_file_opt(fname)
390-
.context("Getting /usr/lib/os-release")?;
391-
392-
let version = os_release.and_then(|os_rel_file| {
393-
let file_contents = match read_file(os_rel_file, &repo) {
394-
Ok(c) => c,
395-
Err(e) => {
396-
tracing::warn!("Could not read /usr/lib/os-release: {e:?}");
397-
return None;
398-
}
399-
};
400-
401-
let file_contents = match std::str::from_utf8(&file_contents) {
402-
Ok(c) => c,
403-
Err(..) => {
404-
tracing::warn!("/usr/lib/os-release did not have valid UTF-8");
405-
return None;
406-
}
407-
};
408-
409-
OsReleaseInfo::parse(file_contents).get_version()
410-
});
411-
412431
let default_sort_key = "1";
432+
let default_title_version = (id.to_hex(), default_sort_key.to_string());
433+
434+
let osrel_res = osrel_title_and_version(fs, &repo)?;
435+
436+
let (title, version) = match osrel_res {
437+
Some((t, v)) => (
438+
t.unwrap_or(default_title_version.0),
439+
v.unwrap_or(default_title_version.1),
440+
),
441+
442+
None => default_title_version,
443+
};
413444

414445
let mut bls_config = BLSConfig::default();
415446

416447
bls_config
417-
.with_title(id_hex.clone())
448+
.with_title(title)
418449
.with_sort_key(default_sort_key.into())
419-
.with_version(version.unwrap_or(default_sort_key.into()))
450+
.with_version(version)
420451
.with_linux(format!(
421452
"/{}/{id_hex}/vmlinuz",
422453
entry_paths.abs_entries_path
@@ -427,82 +458,70 @@ pub(crate) fn setup_composefs_bls_boot(
427458
)])
428459
.with_options(cmdline_refs);
429460

430-
if let Some(symlink_to) = find_vmlinuz_initrd_duplicates(&boot_digest)? {
431-
bls_config.linux =
432-
format!("/{}/{symlink_to}/vmlinuz", entry_paths.abs_entries_path);
461+
match find_vmlinuz_initrd_duplicates(&boot_digest)? {
462+
Some(symlink_to) => {
463+
bls_config.linux =
464+
format!("/{}/{symlink_to}/vmlinuz", entry_paths.abs_entries_path);
433465

434-
bls_config.initrd = vec![format!(
435-
"/{}/{symlink_to}/initrd",
436-
entry_paths.abs_entries_path
437-
)];
438-
} else {
439-
write_bls_boot_entries_to_disk(
440-
&entry_paths.entries_path,
441-
id,
442-
usr_lib_modules_vmlinuz,
443-
&repo,
444-
)?;
445-
}
466+
bls_config.initrd = vec![format!(
467+
"/{}/{symlink_to}/initrd",
468+
entry_paths.abs_entries_path
469+
)];
470+
}
471+
472+
None => {
473+
write_bls_boot_entries_to_disk(
474+
&entry_paths.entries_path,
475+
id,
476+
usr_lib_modules_vmlinuz,
477+
&repo,
478+
)?;
479+
}
480+
};
446481

447482
(bls_config, boot_digest)
448483
}
449484
};
450485

486+
let loader_path = entry_paths.config_path.join("loader");
487+
451488
let (config_path, booted_bls) = if is_upgrade {
452489
let mut booted_bls = get_booted_bls()?;
453490
booted_bls.sort_key = Some("0".into()); // entries are sorted by their filename in reverse order
454491

455492
// This will be atomically renamed to 'loader/entries' on shutdown/reboot
456493
(
457-
entry_paths
458-
.config_path
459-
.join("loader")
460-
.join(STAGED_BOOT_LOADER_ENTRIES),
494+
loader_path.join(STAGED_BOOT_LOADER_ENTRIES),
461495
Some(booted_bls),
462496
)
463497
} else {
464-
(
465-
entry_paths
466-
.config_path
467-
.join("loader")
468-
.join(BOOT_LOADER_ENTRIES),
469-
None,
470-
)
498+
(loader_path.join(BOOT_LOADER_ENTRIES), None)
471499
};
472500

473501
create_dir_all(&config_path).with_context(|| format!("Creating {:?}", config_path))?;
474502

475-
// Scope to allow for proper unmounting
476-
{
477-
let loader_entries_dir = Dir::open_ambient_dir(&config_path, ambient_authority())
478-
.with_context(|| format!("Opening {config_path:?}"))?;
503+
let loader_entries_dir = Dir::open_ambient_dir(&config_path, ambient_authority())
504+
.with_context(|| format!("Opening {config_path:?}"))?;
505+
506+
loader_entries_dir.atomic_write(
507+
// SAFETY: We set sort_key above
508+
type1_entry_conf_file_name(bls_config.sort_key.as_ref().unwrap()),
509+
bls_config.to_string().as_bytes(),
510+
)?;
479511

512+
if let Some(booted_bls) = booted_bls {
480513
loader_entries_dir.atomic_write(
481514
// SAFETY: We set sort_key above
482-
format!(
483-
"bootc-composefs-{}.conf",
484-
bls_config.sort_key.as_ref().unwrap()
485-
),
486-
bls_config.to_string().as_bytes(),
515+
type1_entry_conf_file_name(booted_bls.sort_key.as_ref().unwrap()),
516+
booted_bls.to_string().as_bytes(),
487517
)?;
518+
}
488519

489-
if let Some(booted_bls) = booted_bls {
490-
loader_entries_dir.atomic_write(
491-
// SAFETY: We set sort_key above
492-
format!(
493-
"bootc-composefs-{}.conf",
494-
booted_bls.sort_key.as_ref().unwrap()
495-
),
496-
booted_bls.to_string().as_bytes(),
497-
)?;
498-
}
499-
500-
let owned_loader_entries_fd = loader_entries_dir
501-
.reopen_as_ownedfd()
502-
.context("Reopening as owned fd")?;
520+
let owned_loader_entries_fd = loader_entries_dir
521+
.reopen_as_ownedfd()
522+
.context("Reopening as owned fd")?;
503523

504-
rustix::fs::fsync(owned_loader_entries_fd).context("fsync")?;
505-
}
524+
rustix::fs::fsync(owned_loader_entries_fd).context("fsync")?;
506525

507526
Ok(boot_digest)
508527
}

crates/lib/src/bootc_composefs/status.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{io::Read, sync::OnceLock, u16};
1+
use std::{io::Read, sync::OnceLock};
22

33
use anyhow::{Context, Result};
44
use bootc_kernel_cmdline::utf8::Cmdline;

0 commit comments

Comments
 (0)