Skip to content

Commit 2c5c22f

Browse files
cgwaltersJohan-Liebert1
authored andcommitted
status: Enhance composefs cmdline parsing to handle ?
The duplication between this and composefs-boot is high and we need to squash it; an important step there would probably be lowering the karg parsing. Signed-off-by: Colin Walters <[email protected]>
1 parent 6e18a09 commit 2c5c22f

File tree

1 file changed

+49
-14
lines changed

1 file changed

+49
-14
lines changed

crates/lib/src/status.rs

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,47 @@ impl From<ImageSignature> for ostree_container::SignatureSource {
6363
}
6464
}
6565

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

81109
/// Fixme lower serializability into ostree-ext
@@ -461,13 +489,9 @@ async fn boot_entry_from_composefs_deployment(
461489

462490
#[context("Getting composefs deployment status")]
463491
pub(crate) async fn composefs_deployment_status() -> Result<Host> {
464-
let cmdline = Cmdline::from_proc()?;
465-
let composefs_arg = cmdline
466-
.find_str(COMPOSEFS_CMDLINE)
492+
let composefs_state = composefs_booted()?
467493
.ok_or_else(|| anyhow::anyhow!("Failed to find composefs parameter in kernel cmdline"))?;
468-
let booted_image_verity = composefs_arg
469-
.value
470-
.ok_or_else(|| anyhow::anyhow!("Missing value for composefs"))?;
494+
let composefs_digest = &composefs_state.digest;
471495

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

535-
if depl.file_name() == booted_image_verity {
559+
if depl.file_name() == composefs_digest.as_ref() {
536560
host.spec.image = boot_entry.image.as_ref().map(|x| x.image.clone());
537561
host.status.booted = Some(boot_entry);
538562
continue;
@@ -563,7 +587,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
563587
.options
564588
.as_ref()
565589
.ok_or(anyhow::anyhow!("options key not found in bls config"))?
566-
.contains(composefs_arg.as_ref());
590+
.contains(composefs_digest.as_ref());
567591
}
568592

569593
BootType::Uki => {
@@ -574,7 +598,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
574598
.ok_or(anyhow::anyhow!("First boot entry not found"))?
575599
.body
576600
.chainloader
577-
.contains(composefs_arg.as_ref())
601+
.contains(composefs_digest.as_ref())
578602
}
579603
};
580604

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

0 commit comments

Comments
 (0)