Skip to content

Commit cf60f89

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 6f51546 commit cf60f89

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
@@ -28,15 +28,16 @@ use ostree_ext::sysroot::SysrootLock;
2828
use schemars::schema_for;
2929
use serde::{Deserialize, Serialize};
3030

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

4243
/// Shared progress options
@@ -1128,29 +1129,21 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
11281129

11291130
/// Implementation of the `bootc rollback` CLI command.
11301131
#[context("Rollback")]
1131-
async fn rollback(opts: RollbackOpts) -> Result<()> {
1132-
if composefs_booted()?.is_some() {
1133-
composefs_rollback().await?
1134-
} else {
1135-
let sysroot = &get_storage().await?;
1136-
let ostree = sysroot.get_ostree()?;
1137-
crate::deploy::rollback(sysroot).await?;
1138-
1139-
if opts.soft_reboot.is_some() {
1140-
// Get status of rollback deployment to check soft-reboot capability
1141-
let host = crate::status::get_status_require_booted(ostree)?.2;
1142-
1143-
handle_soft_reboot(
1144-
opts.soft_reboot,
1145-
host.status.rollback.as_ref(),
1146-
"rollback",
1147-
|| soft_reboot_rollback(ostree),
1148-
)?;
1149-
}
1150-
};
1132+
async fn rollback(opts: &RollbackOpts) -> Result<()> {
1133+
let sysroot = &get_storage().await?;
1134+
let ostree = sysroot.get_ostree()?;
1135+
crate::deploy::rollback(sysroot).await?;
11511136

1152-
if opts.apply {
1153-
crate::reboot::reboot()?;
1137+
if opts.soft_reboot.is_some() {
1138+
// Get status of rollback deployment to check soft-reboot capability
1139+
let host = crate::status::get_status_require_booted(ostree)?.2;
1140+
1141+
handle_soft_reboot(
1142+
opts.soft_reboot,
1143+
host.status.rollback.as_ref(),
1144+
"rollback",
1145+
|| soft_reboot_rollback(ostree),
1146+
)?;
11541147
}
11551148

11561149
Ok(())
@@ -1298,20 +1291,44 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
12981291
let root = &Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
12991292
match opt {
13001293
Opt::Upgrade(opts) => {
1294+
#[cfg(feature = "composefs-backend")]
13011295
if composefs_booted()?.is_some() {
13021296
upgrade_composefs(opts).await
13031297
} else {
13041298
upgrade(opts).await
13051299
}
1300+
1301+
#[cfg(not(feature = "composefs-backend"))]
1302+
upgrade(opts).await
13061303
}
13071304
Opt::Switch(opts) => {
1305+
#[cfg(feature = "composefs-backend")]
13081306
if composefs_booted()?.is_some() {
13091307
switch_composefs(opts).await
13101308
} else {
13111309
switch(opts).await
13121310
}
1311+
1312+
#[cfg(not(feature = "composefs-backend"))]
1313+
switch(opts).await
1314+
}
1315+
Opt::Rollback(opts) => {
1316+
#[cfg(feature = "composefs-backend")]
1317+
if composefs_booted()?.is_some() {
1318+
composefs_rollback().await?
1319+
} else {
1320+
rollback(&opts).await?
1321+
}
1322+
1323+
#[cfg(not(feature = "composefs-backend"))]
1324+
rollback(&opts).await?;
1325+
1326+
if opts.apply {
1327+
crate::reboot::reboot()?;
1328+
}
1329+
1330+
Ok(())
13131331
}
1314-
Opt::Rollback(opts) => rollback(opts).await,
13151332
Opt::Edit(opts) => edit(opts).await,
13161333
Opt::UsrOverlay => usroverlay().await,
13171334
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)