Skip to content

Commit a266a4c

Browse files
cfs/rollback: Update the way we get rollback
Instead of blindly selecting the "second" one in a list of sorted boot entries as the rollback and failing if there are more than one rollback candidate, sort the rollback candidates in the same order as the boot entries and take the first one as rollback. All the remaining deployments become `other_deployments`. This is especially useful if and when we implement pinned deployments for composefs Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
1 parent ca51e49 commit a266a4c

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

crates/lib/src/bootc_composefs/status.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{collections::HashSet, io::Read, sync::OnceLock};
1+
use std::{io::Read, sync::OnceLock};
22

33
use anyhow::{Context, Result};
44
use bootc_kernel_cmdline::utf8::Cmdline;
@@ -831,7 +831,6 @@ async fn composefs_deployment_status_from(
831831
Err(e) => Err(e),
832832
}?;
833833

834-
// NOTE: This cannot work if we support both BLS and UKI at the same time
835834
let mut boot_type: Option<BootType> = None;
836835

837836
// Boot entries from deployments that are neither booted nor staged deployments
@@ -966,6 +965,8 @@ async fn composefs_deployment_status_from(
966965

967966
// Determine rollback deployment by matching extra deployment boot entries against entires read from /boot
968967
// This collects verity digest across bls and grub enties, we should just have one of them, but still works
968+
//
969+
// We want this ordered, so we have a vector here
969970
let bootloader_configured_verity = sorted_bls_config
970971
.iter()
971972
.flatten()
@@ -976,9 +977,9 @@ async fn composefs_deployment_status_from(
976977
.flatten()
977978
.map(|menu| menu.get_verity()),
978979
)
979-
.collect::<Result<HashSet<_>>>()?;
980+
.collect::<Result<Vec<_>>>()?;
980981

981-
let rollback_candidates: Vec<_> = extra_deployment_boot_entries
982+
let mut rollback_candidates: Vec<_> = extra_deployment_boot_entries
982983
.into_iter()
983984
.filter(|entry| {
984985
let verity = &entry
@@ -990,10 +991,22 @@ async fn composefs_deployment_status_from(
990991
})
991992
.collect();
992993

993-
if rollback_candidates.len() > 1 {
994-
anyhow::bail!("Multiple extra entries in /boot, could not determine rollback entry");
995-
} else if let Some(rollback_entry) = rollback_candidates.into_iter().next() {
996-
host.status.rollback = Some(rollback_entry);
994+
// We get sorted bootloader entries, so here we re-sort the rollback candidates
995+
// wrt their positions in the sorted bootloader entries as that's what determines
996+
// what's shown on the bootloader menu. The very next boot entry, that's not the
997+
// default should be the rollback
998+
rollback_candidates.sort_by_key(|ent| {
999+
bootloader_configured_verity
1000+
.iter()
1001+
// SAFETY: ent.composefs will definitely exist
1002+
.position(|v| ent.composefs.as_ref().unwrap().verity == *v)
1003+
});
1004+
1005+
if !rollback_candidates.is_empty() {
1006+
let mut iter = rollback_candidates.into_iter();
1007+
1008+
host.status.rollback = iter.next();
1009+
host.status.other_deployments = iter.collect();
9971010
}
9981011

9991012
host.status.rollback_queued = is_rollback_queued;

0 commit comments

Comments
 (0)