Skip to content

Commit 11672aa

Browse files
Gate composefs-native behind composefs-backend flag
Refactor to use `#[cfg(feature = "composefs-backend")]` to gate composefs native features behind the flag. Gate the following features - `--composefs-native` and its corresponding cli args - Installing/Switching/Upgrading/RollingBack of composefs native system - Create separate install, rollback functions for ostree for a bit cleaner of a setup Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 0762035 commit 11672aa

File tree

10 files changed

+244
-154
lines changed

10 files changed

+244
-154
lines changed

crates/lib/src/bootc_composefs/status.rs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
use std::io::Read;
1+
use std::{io::Read, sync::OnceLock};
22

33
use anyhow::{Context, Result};
4+
use bootc_kernel_cmdline::Cmdline;
45
use fn_error_context::context;
56

67
use crate::{
78
bootc_composefs::boot::BootType,
8-
composefs_consts::{BOOT_LOADER_ENTRIES, USER_CFG},
9+
composefs_consts::{BOOT_LOADER_ENTRIES, COMPOSEFS_CMDLINE, USER_CFG},
910
parsers::{
1011
bls_config::{parse_bls_config, BLSConfig},
1112
grub_menuconfig::{parse_grub_menuentry_file, MenuEntry},
1213
},
1314
spec::{BootEntry, BootOrder, Host, HostSpec, ImageReference, ImageStatus},
14-
status::composefs_booted,
1515
};
1616

1717
use std::str::FromStr;
@@ -35,6 +35,49 @@ use crate::composefs_consts::{
3535
use crate::install::EFIVARFS;
3636
use crate::spec::Bootloader;
3737

38+
/// A parsed composefs command line
39+
pub(crate) struct ComposefsCmdline {
40+
#[allow(dead_code)]
41+
pub insecure: bool,
42+
pub digest: Box<str>,
43+
}
44+
45+
impl ComposefsCmdline {
46+
pub(crate) fn new(s: &str) -> Self {
47+
let (insecure, digest_str) = s
48+
.strip_prefix('?')
49+
.map(|v| (true, v))
50+
.unwrap_or_else(|| (false, s));
51+
ComposefsCmdline {
52+
insecure,
53+
digest: digest_str.into(),
54+
}
55+
}
56+
}
57+
58+
impl std::fmt::Display for ComposefsCmdline {
59+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60+
let insecure = if self.insecure { "?" } else { "" };
61+
write!(f, "{}={}{}", COMPOSEFS_CMDLINE, insecure, self.digest)
62+
}
63+
}
64+
65+
/// Detect if we have composefs=<digest> in /proc/cmdline
66+
pub(crate) fn composefs_booted() -> Result<Option<&'static ComposefsCmdline>> {
67+
static CACHED_DIGEST_VALUE: OnceLock<Option<ComposefsCmdline>> = OnceLock::new();
68+
if let Some(v) = CACHED_DIGEST_VALUE.get() {
69+
return Ok(v.as_ref());
70+
}
71+
let cmdline = Cmdline::from_proc()?;
72+
let Some(kv) = cmdline.find_str(COMPOSEFS_CMDLINE) else {
73+
return Ok(None);
74+
};
75+
let Some(v) = kv.value else { return Ok(None) };
76+
let v = ComposefsCmdline::new(v);
77+
let r = CACHED_DIGEST_VALUE.get_or_init(|| Some(v));
78+
Ok(r.as_ref())
79+
}
80+
3881
// Need str to store lifetime
3982
pub(crate) fn get_sorted_uki_boot_entries<'a>(
4083
boot_dir: &Dir,
@@ -336,6 +379,17 @@ mod tests {
336379

337380
use super::*;
338381

382+
#[test]
383+
fn test_composefs_parsing() {
384+
const DIGEST: &str = "8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52";
385+
let v = ComposefsCmdline::new(DIGEST);
386+
assert!(!v.insecure);
387+
assert_eq!(v.digest.as_ref(), DIGEST);
388+
let v = ComposefsCmdline::new(&format!("?{}", DIGEST));
389+
assert!(v.insecure);
390+
assert_eq!(v.digest.as_ref(), DIGEST);
391+
}
392+
339393
#[test]
340394
fn test_sorted_bls_boot_entries() -> Result<()> {
341395
let tempdir = cap_std_ext::cap_tempfile::tempdir(cap_std::ambient_authority())?;

crates/lib/src/cli.rs

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,16 @@ use ostree_ext::sysroot::SysrootLock;
2929
use schemars::schema_for;
3030
use serde::{Deserialize, Serialize};
3131

32-
use crate::bootc_composefs::rollback::composefs_rollback;
33-
use crate::bootc_composefs::switch::switch_composefs;
34-
use crate::bootc_composefs::update::upgrade_composefs;
32+
#[cfg(feature = "composefs-backend")]
33+
use crate::bootc_composefs::{
34+
rollback::composefs_rollback, status::composefs_booted, switch::switch_composefs,
35+
update::upgrade_composefs,
36+
};
3537
use crate::deploy::RequiredHostSpec;
3638
use crate::lints;
3739
use crate::progress_jsonl::{ProgressWriter, RawProgressFd};
3840
use crate::spec::Host;
3941
use crate::spec::ImageReference;
40-
use crate::status::composefs_booted;
4142
use crate::utils::sigpolicy_from_opt;
4243

4344
/// Shared progress options
@@ -1141,29 +1142,21 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
11411142

11421143
/// Implementation of the `bootc rollback` CLI command.
11431144
#[context("Rollback")]
1144-
async fn rollback(opts: RollbackOpts) -> Result<()> {
1145-
if composefs_booted()?.is_some() {
1146-
composefs_rollback().await?
1147-
} else {
1148-
let sysroot = &get_storage().await?;
1149-
let ostree = sysroot.get_ostree()?;
1150-
crate::deploy::rollback(sysroot).await?;
1151-
1152-
if opts.soft_reboot.is_some() {
1153-
// Get status of rollback deployment to check soft-reboot capability
1154-
let host = crate::status::get_status_require_booted(ostree)?.2;
1155-
1156-
handle_soft_reboot(
1157-
opts.soft_reboot,
1158-
host.status.rollback.as_ref(),
1159-
"rollback",
1160-
|| soft_reboot_rollback(ostree),
1161-
)?;
1162-
}
1163-
};
1145+
async fn rollback(opts: &RollbackOpts) -> Result<()> {
1146+
let sysroot = &get_storage().await?;
1147+
let ostree = sysroot.get_ostree()?;
1148+
crate::deploy::rollback(sysroot).await?;
11641149

1165-
if opts.apply {
1166-
crate::reboot::reboot()?;
1150+
if opts.soft_reboot.is_some() {
1151+
// Get status of rollback deployment to check soft-reboot capability
1152+
let host = crate::status::get_status_require_booted(ostree)?.2;
1153+
1154+
handle_soft_reboot(
1155+
opts.soft_reboot,
1156+
host.status.rollback.as_ref(),
1157+
"rollback",
1158+
|| soft_reboot_rollback(ostree),
1159+
)?;
11671160
}
11681161

11691162
Ok(())
@@ -1310,20 +1303,44 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
13101303
let root = &Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
13111304
match opt {
13121305
Opt::Upgrade(opts) => {
1306+
#[cfg(feature = "composefs-backend")]
13131307
if composefs_booted()?.is_some() {
13141308
upgrade_composefs(opts).await
13151309
} else {
13161310
upgrade(opts).await
13171311
}
1312+
1313+
#[cfg(not(feature = "composefs-backend"))]
1314+
upgrade(opts).await
13181315
}
13191316
Opt::Switch(opts) => {
1317+
#[cfg(feature = "composefs-backend")]
13201318
if composefs_booted()?.is_some() {
13211319
switch_composefs(opts).await
13221320
} else {
13231321
switch(opts).await
13241322
}
1323+
1324+
#[cfg(not(feature = "composefs-backend"))]
1325+
switch(opts).await
1326+
}
1327+
Opt::Rollback(opts) => {
1328+
#[cfg(feature = "composefs-backend")]
1329+
if composefs_booted()?.is_some() {
1330+
composefs_rollback().await?
1331+
} else {
1332+
rollback(&opts).await?
1333+
}
1334+
1335+
#[cfg(not(feature = "composefs-backend"))]
1336+
rollback(&opts).await?;
1337+
1338+
if opts.apply {
1339+
crate::reboot::reboot()?;
1340+
}
1341+
1342+
Ok(())
13251343
}
1326-
Opt::Rollback(opts) => rollback(opts).await,
13271344
Opt::Edit(opts) => edit(opts).await,
13281345
Opt::UsrOverlay => usroverlay().await,
13291346
Opt::Container(opts) => match opts {

crates/lib/src/composefs_consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(dead_code)]
2+
13
/// composefs= paramter in kernel cmdline
24
pub const COMPOSEFS_CMDLINE: &str = "composefs";
35

0 commit comments

Comments
 (0)