Skip to content

Commit 017206d

Browse files
authored
Merge pull request bootc-dev#1534 from cgwalters/misc-cfs
A few minor composefs patches
2 parents 1a7ac13 + 31091eb commit 017206d

File tree

2 files changed

+58
-17
lines changed

2 files changed

+58
-17
lines changed

crates/lib/src/install.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,14 +1772,20 @@ pub(crate) fn setup_composefs_bls_boot(
17721772

17731773
loader_entries_dir.atomic_write(
17741774
// SAFETY: We set sort_key above
1775-
format!("bootc-composefs-{}.conf", bls_config.sort_key.as_ref().unwrap()),
1775+
format!(
1776+
"bootc-composefs-{}.conf",
1777+
bls_config.sort_key.as_ref().unwrap()
1778+
),
17761779
bls_config.to_string().as_bytes(),
17771780
)?;
17781781

17791782
if let Some(booted_bls) = booted_bls {
17801783
loader_entries_dir.atomic_write(
17811784
// SAFETY: We set sort_key above
1782-
format!("bootc-composefs-{}.conf", booted_bls.sort_key.as_ref().unwrap()),
1785+
format!(
1786+
"bootc-composefs-{}.conf",
1787+
booted_bls.sort_key.as_ref().unwrap()
1788+
),
17831789
booted_bls.to_string().as_bytes(),
17841790
)?;
17851791
}

crates/lib/src/status.rs

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,47 @@ impl From<ImageSignature> for ostree_container::SignatureSource {
6262
}
6363
}
6464

65+
/// A parsed composefs command line
66+
pub(crate) struct ComposefsCmdline {
67+
#[allow(dead_code)]
68+
pub insecure: bool,
69+
pub digest: Box<str>,
70+
}
71+
72+
impl ComposefsCmdline {
73+
pub(crate) fn new(s: &str) -> Self {
74+
let (insecure, digest_str) = s
75+
.strip_prefix('?')
76+
.map(|v| (true, v))
77+
.unwrap_or_else(|| (false, s));
78+
ComposefsCmdline {
79+
insecure,
80+
digest: digest_str.into(),
81+
}
82+
}
83+
}
84+
85+
impl std::fmt::Display for ComposefsCmdline {
86+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87+
let insecure = if self.insecure { "?" } else { "" };
88+
write!(f, "{}={}{}", COMPOSEFS_CMDLINE, insecure, self.digest)
89+
}
90+
}
91+
6592
/// Detect if we have composefs=<digest> in /proc/cmdline
66-
pub(crate) fn composefs_booted() -> Result<Option<&'static str>> {
67-
static CACHED_DIGEST_VALUE: OnceLock<Option<String>> = OnceLock::new();
93+
pub(crate) fn composefs_booted() -> Result<Option<&'static ComposefsCmdline>> {
94+
static CACHED_DIGEST_VALUE: OnceLock<Option<ComposefsCmdline>> = OnceLock::new();
6895
if let Some(v) = CACHED_DIGEST_VALUE.get() {
69-
return Ok(v.as_deref());
96+
return Ok(v.as_ref());
7097
}
7198
let cmdline = crate::kernel_cmdline::Cmdline::from_proc()?;
72-
let Some(kv) = cmdline.find_str("composefs") else {
99+
let Some(kv) = cmdline.find_str(COMPOSEFS_CMDLINE) else {
73100
return Ok(None);
74101
};
75102
let Some(v) = kv.value else { return Ok(None) };
76-
let r = CACHED_DIGEST_VALUE.get_or_init(|| Some(v.to_owned()));
77-
Ok(r.as_deref())
103+
let v = ComposefsCmdline::new(v);
104+
let r = CACHED_DIGEST_VALUE.get_or_init(|| Some(v));
105+
Ok(r.as_ref())
78106
}
79107

80108
/// Fixme lower serializability into ostree-ext
@@ -460,13 +488,9 @@ async fn boot_entry_from_composefs_deployment(
460488

461489
#[context("Getting composefs deployment status")]
462490
pub(crate) async fn composefs_deployment_status() -> Result<Host> {
463-
let cmdline = crate::kernel_cmdline::Cmdline::from_proc()?;
464-
let composefs_arg = cmdline
465-
.find_str(COMPOSEFS_CMDLINE)
491+
let composefs_state = composefs_booted()?
466492
.ok_or_else(|| anyhow::anyhow!("Failed to find composefs parameter in kernel cmdline"))?;
467-
let booted_image_verity = composefs_arg
468-
.value
469-
.ok_or_else(|| anyhow::anyhow!("Missing value for composefs"))?;
493+
let composefs_digest = &composefs_state.digest;
470494

471495
let sysroot = cap_std::fs::Dir::open_ambient_dir("/sysroot", cap_std::ambient_authority())
472496
.context("Opening sysroot")?;
@@ -531,7 +555,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
531555
}
532556
};
533557

534-
if depl.file_name() == booted_image_verity {
558+
if depl.file_name() == composefs_digest.as_ref() {
535559
host.spec.image = boot_entry.image.as_ref().map(|x| x.image.clone());
536560
host.status.booted = Some(boot_entry);
537561
continue;
@@ -562,7 +586,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
562586
.options
563587
.as_ref()
564588
.ok_or(anyhow::anyhow!("options key not found in bls config"))?
565-
.contains(composefs_arg.as_ref());
589+
.contains(composefs_digest.as_ref());
566590
}
567591

568592
BootType::Uki => {
@@ -573,7 +597,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
573597
.ok_or(anyhow::anyhow!("First boot entry not found"))?
574598
.body
575599
.chainloader
576-
.contains(composefs_arg.as_ref())
600+
.contains(composefs_digest.as_ref())
577601
}
578602
};
579603

@@ -1082,4 +1106,15 @@ mod tests {
10821106
assert!(w.contains("Commit:"));
10831107
assert!(w.contains("Soft-reboot:"));
10841108
}
1109+
1110+
#[test]
1111+
fn test_composefs_parsing() {
1112+
const DIGEST: &str = "8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52";
1113+
let v = ComposefsCmdline::new(DIGEST);
1114+
assert!(!v.insecure);
1115+
assert_eq!(v.digest.as_ref(), DIGEST);
1116+
let v = ComposefsCmdline::new(&format!("?{}", DIGEST));
1117+
assert!(v.insecure);
1118+
assert_eq!(v.digest.as_ref(), DIGEST);
1119+
}
10851120
}

0 commit comments

Comments
 (0)