From e054db031b2f6ecab85ad4587ef8f5ef64b342fd Mon Sep 17 00:00:00 2001 From: Joe Date: Thu, 28 Aug 2025 12:48:01 -0700 Subject: [PATCH] fix: Improve EFI component error handling for non-OSTree systems - Fix EFI component Drop implementation to only unmount when mountpoint exists - Prevent 'No such file or directory' errors during EFI component cleanup - Add graceful error handling in generate_update_metadata for component failures - Allow metadata generation to continue even when some components fail - Provide clear warning messages for failed components - Maintain system stability during EFI component operations --- src/bootupd.rs | 38 +++++++++++++++++++++++++++++++------- src/efi.rs | 15 +++++++++++---- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index d74323e..2534d63 100755 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -217,15 +217,39 @@ pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { let updates_dir = Path::new(sysroot_path).join(crate::model::BOOTUPD_UPDATES_DIR); std::fs::create_dir_all(&updates_dir) .with_context(|| format!("Failed to create updates dir {:?}", &updates_dir))?; + + let mut successful_components = 0; + let mut failed_components = Vec::new(); + for component in get_components().values() { - let v = component.generate_update_metadata(sysroot_path)?; - println!( - "Generated update layout for {}: {}", - component.name(), - v.version, - ); + match component.generate_update_metadata(sysroot_path) { + Ok(v) => { + println!( + "Generated update layout for {}: {}", + component.name(), + v.version, + ); + successful_components += 1; + } + Err(e) => { + let error_msg = format!("{}: {}", component.name(), e); + println!("Warning: Failed to generate metadata for {}: {}", component.name(), e); + failed_components.push(error_msg); + } + } } - + + // If no components succeeded, return an error + if successful_components == 0 { + anyhow::bail!("Failed to generate metadata for any components: {}", failed_components.join("; ")); + } + + // If some components failed, log a warning but continue + if !failed_components.is_empty() { + println!("Note: {} component(s) failed, but {} component(s) succeeded", + failed_components.len(), successful_components); + } + Ok(()) } diff --git a/src/efi.rs b/src/efi.rs index 14bf6c9..0eabbdd 100755 --- a/src/efi.rs +++ b/src/efi.rs @@ -467,7 +467,7 @@ impl Component for Efi { // move EFI files to updates dir from /usr/lib/ostree-boot if ostreebootdir.exists() { let grub_dir_name = debian_tools::get_grub_dir_name(); - let cruft = ["loader", grub_dir_name]; + let cruft = ["loader", grub_dir_name]; for p in cruft.iter() { let p = ostreebootdir.join(p); if p.exists() { @@ -495,7 +495,9 @@ impl Component for Efi { }); packagesystem::query_files(sysroot, files)? } else { - anyhow::bail!("Failed to find {ostreebootdir}"); + // On non-OSTree systems (like regular Debian), we can't generate EFI metadata + // Return a special error that indicates this component should be skipped + anyhow::bail!("EFI component not available on non-OSTree system: {ostreebootdir} not found"); } }; @@ -570,8 +572,13 @@ impl Component for Efi { impl Drop for Efi { fn drop(&mut self) { - log::debug!("Unmounting"); - let _ = self.unmount(); + // Only try to unmount if we actually have a mountpoint + if self.mountpoint.borrow().is_some() { + log::debug!("Unmounting"); + let _ = self.unmount(); + } else { + log::debug!("No mountpoint to unmount"); + } } }