Skip to content

Commit 77a9cab

Browse files
composefs/status: Check if deployment is soft rebootable
Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 2c34df6 commit 77a9cab

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

crates/lib/src/bootc_composefs/status.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ pub(crate) async fn get_composefs_status(
258258
composefs_deployment_status_from(&storage, booted_cfs.cmdline).await
259259
}
260260

261+
fn set_reboot_capable(deployment: &mut BootEntry, booted_boot_digest: &String) -> Result<()> {
262+
let boot_digest = deployment.composefs_boot_digest()?;
263+
deployment.soft_reboot_capable = boot_digest == booted_boot_digest;
264+
Ok(())
265+
}
266+
261267
#[context("Getting composefs deployment status")]
262268
pub(crate) async fn composefs_deployment_status_from(
263269
storage: &Storage,
@@ -350,9 +356,9 @@ pub(crate) async fn composefs_deployment_status_from(
350356
anyhow::bail!("Could not determine boot type");
351357
};
352358

353-
let booted = host.require_composefs_booted()?;
359+
let booted_cfs = host.require_composefs_booted()?;
354360

355-
let is_rollback_queued = match booted.bootloader {
361+
let is_rollback_queued = match booted_cfs.bootloader {
356362
Bootloader::Grub => match boot_type {
357363
BootType::Bls => {
358364
let bls_config = get_sorted_type1_boot_entries(boot_dir, false)?;
@@ -413,6 +419,29 @@ pub(crate) async fn composefs_deployment_status_from(
413419
host.spec.boot_order = BootOrder::Rollback
414420
};
415421

422+
// Can only soft reboot non UKI boot entries
423+
if !matches!(boot_type, BootType::Uki) {
424+
let booted_mut = host
425+
.status
426+
.booted
427+
.as_mut()
428+
.ok_or_else(|| anyhow::anyhow!("Failed to find booted entry"))?;
429+
430+
let booted_boot_digest = booted_mut.composefs_boot_digest()?;
431+
432+
if let Some(staged) = host.status.staged.as_mut() {
433+
set_reboot_capable(staged, booted_boot_digest)?;
434+
}
435+
436+
if let Some(rollback) = host.status.rollback.as_mut() {
437+
set_reboot_capable(rollback, booted_boot_digest)?;
438+
}
439+
440+
for deployment in &mut host.status.other_deployments {
441+
set_reboot_capable(deployment, booted_boot_digest)?;
442+
}
443+
}
444+
416445
Ok(host)
417446
}
418447

crates/lib/src/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use std::sync::Arc;
1111

1212
use anyhow::{anyhow, ensure, Context, Result};
1313
use camino::{Utf8Path, Utf8PathBuf};
14-
use cap_std_ext::cap_std;
1514
use cap_std_ext::cap_std::fs::Dir;
15+
use cap_std_ext::cap_std;
1616
use clap::Parser;
1717
use clap::ValueEnum;
1818
use composefs::dumpfile;

crates/lib/src/status.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,13 @@ impl BootEntry {
307307
"BootEntry is not a composefs native boot entry"
308308
))
309309
}
310+
311+
pub(crate) fn composefs_boot_digest(&self) -> Result<&String> {
312+
self.require_composefs()?
313+
.boot_digest
314+
.as_ref()
315+
.ok_or_else(|| anyhow::anyhow!("Could not find boot digest for deployment"))
316+
}
310317
}
311318

312319
/// A variant of [`get_status`] that requires a booted deployment.

0 commit comments

Comments
 (0)