-
Notifications
You must be signed in to change notification settings - Fork 140
composefs: Add missed commits when rebasing #1502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
composefs: Add missed commits when rebasing #1502
Conversation
Parse the Grub menuentry file, `boot/grub2/user.cfg` to get a list of bootable UKIs and figure out if a rollback is currently queued. Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request incorporates a number of commits that were missed during a previous rebase. The changes include significant refactoring, such as moving parsers to a dedicated module and centralizing constants, which improves code organization. The introduction of boot digest computation to avoid duplicating kernel and initrd files is a good optimization.
My review has identified a few critical issues. There are a couple of assert!
macros that should be replaced with proper error handling to prevent panics in debug builds and undefined behavior in release builds. I also found a typo in kernel argument formatting that would lead to an invalid argument, and an incorrect usage of unlinkat
for directory removal that would cause an error.
Apart from these issues, the changes look good and improve the codebase.
get_sorted_uki_boot_entries(&boot_dir, &mut str).context("Getting UKI boot entries")?; | ||
|
||
// TODO(Johan-Liebert): Currently assuming there are only two deployments | ||
assert!(menuentries.len() == 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of assert!
here can lead to a panic in debug builds or incorrect behavior in release builds if the number of menu entries is not exactly 2. It's better to return an error, especially since the TODO
comment acknowledges this is a known limitation.
assert!(menuentries.len() == 2); | |
if menuentries.len() != 2 { | |
anyhow::bail!("Expected exactly 2 UKI boot entries, found {}", menuentries.len()); | |
} |
} | ||
|
||
// TODO(Johan-Liebert): Currently assuming there are only two deployments | ||
assert!(all_configs.len() == 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the UKI rollback logic, this assert!
can cause a panic in debug builds or lead to incorrect behavior in release builds. It should be replaced with proper error handling.
assert!(all_configs.len() == 2); | |
if all_configs.len() != 2 { | |
anyhow::bail!("Expected exactly 2 BLS boot entries, found {}", all_configs.len()); | |
} |
crates/lib/src/install.rs
Outdated
} | ||
None | Some(..) => { | ||
cmdline_options.push_str(&format!(" composefs={id_hex}")); | ||
cmdline_options.push_str(&format!(" {COMPOSEFS_CMDLINE}{id_hex}")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be a missing =
in the format string. This will generate an invalid kernel argument composefs<id_hex>
instead of composefs=<id_hex>
.
cmdline_options.push_str(&format!(" {COMPOSEFS_CMDLINE}{id_hex}")); | |
cmdline_options.push_str(&format!(" {COMPOSEFS_CMDLINE}={id_hex}")); |
rustix::fs::unlinkat(&dir, ROLLBACK_BOOT_LOADER_ENTRIES, AtFlags::empty()) | ||
.context("unlinkat")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unlinkat
call with AtFlags::empty()
will fail with EISDIR
because ROLLBACK_BOOT_LOADER_ENTRIES
refers to a directory. The previous code with AtFlags::REMOVEDIR
would also fail because the directory is not empty. To remove a directory and its contents, you should use a recursive removal function like remove_dir_all
.
rustix::fs::unlinkat(&dir, ROLLBACK_BOOT_LOADER_ENTRIES, AtFlags::empty()) | |
.context("unlinkat")?; | |
dir.remove_dir_all(ROLLBACK_BOOT_LOADER_ENTRIES) | |
.with_context(|| format!("Removing directory {}", ROLLBACK_BOOT_LOADER_ENTRIES))?; |
crates/lib/src/install.rs
Outdated
format!("root=UUID={DPS_UUID}"), | ||
RW_KARG.to_string(), | ||
format!("composefs={id_hex}"), | ||
format!("{COMPOSEFS_CMDLINE}{id_hex}"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
=
missing here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, Gemini found the other one of this.
crates/lib/src/bls_config.rs
Outdated
pub(crate) fn to_string(&self) -> String { | ||
let mut out = String::new(); | ||
|
||
impl Display for BLSConfig { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should've been moved to lib/src/parsers/bls_config.rs
and indeed it has been. This piece seems leftover
/// Body content of a GRUB menuentry containing parsed commands. | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub(crate) struct MenuentryBody<'a> { | ||
/// Kernel modules to load |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cgwalters The changes you made, and the ones we pushed to main, seem to have been overwritten here. I think we should keep your changes for this particular file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just the added comments right? The rest of this was changing things here to use an owned value for chainloader per your previous commit.
(That said, it's weird to have a mix of borrowed and owned data here...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is kinda weird, but getting rust to return a local ref without Box::leak
is pretty complicated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's https://lib.rs/crates/yoke among others
Returning a local reference to a `&str` is quite tricky with rust. Update `title` and `chainloader`, the two dynamic fields in the grub menuentry, to be `String` instead of `&str` Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
We parse the grub menuentries, get the rollback deployment then perform the rollback, which basically consists of writing a new .staged menuentry file then atomically swapping the staged and the current menuentry. Rollback while there is a staged deployment is still to be handled. Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
…iles Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
If two deployments have the same VMLinuz + Initrd then, we can use the same binaries for both the deployments. Before writing the BLS entries to disk we calculate the SHA256Sum of VMLinuz + Initrd combo, then test if any other deployment has the same SHA256Sum for the binaries. Store the hash in the origin file under `boot -> hash` for future lookups. Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Centralize all constants in a separate file Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Instead of `/sysroot/state/os/fedora` use `/sysroot/state/os/default` as the default state directory. Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Instaed of writing all present menuentries, only write the menuentry for switch/upgrade and the menuentry for the currently booted deployment. Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
Signed-off-by: Johan-Liebert1 <pragyanpoudyal41999@gmail.com>
This allows for easier testing Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
Add tests for functions `get_sorted_bls_boot_entries` and `get_sorted_uki_boot_entries` Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
3348aba
to
95bbfe6
Compare
OK, updated |
centos-10 tests seem to be failing due to package conflicts. Else LGTM
|
Yeah that's https://gitlab.com/redhat/centos-stream/containers/bootc/-/issues/1174 - unrelated to this PR |
I messed up the previous rebase/squash of the composefs branch. This adds commits since c89efab
There were definitely some messy conflicts, but this at least compiles