@@ -568,50 +568,49 @@ impl Component for Efi {
568568 }
569569
570570 fn generate_update_metadata ( & self , sysroot : & str ) -> Result < Option < ContentMetadata > > {
571- let sysroot_path = Path :: new ( sysroot) ;
571+ let sysroot_path = Utf8Path :: new ( sysroot) ;
572572 let sysroot_dir = Dir :: open_ambient_dir ( sysroot_path, cap_std:: ambient_authority ( ) ) ?;
573573
574- if let Some ( ostreeboot) = sysroot_dir
574+ let ostreeboot = sysroot_dir
575575 . open_dir_optional ( ostreeutil:: BOOT_PREFIX )
576- . context ( "Opening usr/lib/ostree-boot" ) ?
577- {
576+ . context ( "Opening usr/lib/ostree-boot" ) ?;
577+
578+ // Newer images >= F44 have boot entries in /usr/lib/efi, but older images
579+ // have them in /usr/lib/ostree-boot, which we move to /usr/lib/bootupd/updates/EFI
580+ let metadata = if sysroot_path. join ( EFILIB ) . exists ( ) {
581+ println ! ( "Generating metadata from {EFILIB}" ) ;
582+ generate_meta_from_usr_efi ( sysroot_path) ?
583+ } else {
584+ match & ostreeboot {
585+ Some ( ..) => {
586+ println ! (
587+ "Moving {}/efi/EFI to {BOOTUPD_UPDATES_DIR}/EFI" ,
588+ ostreeutil:: BOOT_PREFIX
589+ ) ;
590+ // Transfer usr/lib/ostree-boot/EFI files to usr/lib/bootupd/updates/EFI
591+ transfer_ostree_boot_to_bootupd_updates ( sysroot_path, self ) ?
592+ }
593+
594+ // If /usr/lib/ostree-boot doesn't exist, assume /usr/lib/efi will
595+ None => anyhow:: bail!( "/usr/lib/ostree-boot and /usr/lib/efi not found" ) ,
596+ }
597+ } ;
598+
599+ if let Some ( ostreeboot) = ostreeboot {
578600 let cruft = [ "loader" , "grub2" ] ;
579601 for p in cruft. iter ( ) {
602+ println ! ( "Removing {p} from {}" , ostreeutil:: BOOT_PREFIX ) ;
580603 ostreeboot. remove_all_optional ( p) ?;
581604 }
582- // Transfer ostree-boot EFI files to usr/lib/efi
583- transfer_ostree_boot_to_usr ( sysroot_path) ?;
584605
606+ println ! ( "Removing efi/EFI from {}" , ostreeutil:: BOOT_PREFIX ) ;
585607 // Remove usr/lib/ostree-boot/efi/EFI dir (after transfer) or if it is empty
586608 ostreeboot. remove_all_optional ( "efi/EFI" ) ?;
587- }
609+ } ;
588610
589- if let Some ( efi_components) =
590- get_efi_component_from_usr ( Utf8Path :: from_path ( sysroot_path) . unwrap ( ) , EFILIB ) ?
591- {
592- let mut packages = Vec :: new ( ) ;
593- let mut modules_vec: Vec < Module > = vec ! [ ] ;
594- for efi in efi_components {
595- packages. push ( format ! ( "{}-{}" , efi. name, efi. version) ) ;
596- modules_vec. push ( Module {
597- name : efi. name ,
598- rpm_evr : efi. version ,
599- } ) ;
600- }
601- modules_vec. sort_unstable ( ) ;
602-
603- // change to now to workaround https://github.com/coreos/bootupd/issues/933
604- let timestamp = std:: time:: SystemTime :: now ( ) ;
605- let meta = ContentMetadata {
606- timestamp : chrono:: DateTime :: < Utc > :: from ( timestamp) ,
607- version : packages. join ( "," ) ,
608- versions : Some ( modules_vec) ,
609- } ;
610- write_update_metadata ( sysroot, self , & meta) ?;
611- Ok ( Some ( meta) )
612- } else {
613- anyhow:: bail!( "Failed to find EFI components" ) ;
614- }
611+ write_update_metadata ( sysroot_path. as_str ( ) , self , & metadata) ?;
612+
613+ Ok ( Some ( metadata) )
615614 }
616615
617616 fn query_update ( & self , sysroot : & openat:: Dir ) -> Result < Option < ContentMetadata > > {
@@ -801,6 +800,34 @@ fn find_file_recursive<P: AsRef<Path>>(dir: P, target_file: &str) -> Result<Vec<
801800 Ok ( result)
802801}
803802
803+ #[ context( "Generating metadata from usr/lib/efi" ) ]
804+ fn generate_meta_from_usr_efi ( sysroot_path : & Utf8Path ) -> Result < ContentMetadata > {
805+ let Some ( efi_components) = get_efi_component_from_usr ( sysroot_path, EFILIB ) ? else {
806+ anyhow:: bail!( "Failed to find EFI components" ) ;
807+ } ;
808+
809+ let mut packages = Vec :: new ( ) ;
810+ let mut modules_vec: Vec < Module > = vec ! [ ] ;
811+ for efi in efi_components {
812+ packages. push ( format ! ( "{}-{}" , efi. name, efi. version) ) ;
813+ modules_vec. push ( Module {
814+ name : efi. name ,
815+ rpm_evr : efi. version ,
816+ } ) ;
817+ }
818+ modules_vec. sort_unstable ( ) ;
819+
820+ // change to now to workaround https://github.com/coreos/bootupd/issues/933
821+ let timestamp = std:: time:: SystemTime :: now ( ) ;
822+ let meta = ContentMetadata {
823+ timestamp : chrono:: DateTime :: < Utc > :: from ( timestamp) ,
824+ version : packages. join ( "," ) ,
825+ versions : Some ( modules_vec) ,
826+ } ;
827+
828+ Ok ( meta)
829+ }
830+
804831#[ derive( Debug , PartialEq , Eq ) ]
805832pub struct EFIComponent {
806833 pub name : String ,
@@ -851,57 +878,43 @@ fn get_efi_component_from_usr<'a>(
851878 Ok ( Some ( components) )
852879}
853880
854- /// Copy files from usr/lib/ostree-boot/efi/EFI to /usr/lib/efi/<component>/<evr>/
855- fn transfer_ostree_boot_to_usr ( sysroot : & Path ) -> Result < ( ) > {
856- let ostreeboot_efi = Path :: new ( ostreeutil:: BOOT_PREFIX ) . join ( "efi" ) ;
857- let ostreeboot_efi_path = sysroot. join ( & ostreeboot_efi) ;
881+ /// Copies usr/lib/ostree-boot/EFI to usr/lib/bootupd/updates
882+ fn transfer_ostree_boot_to_bootupd_updates (
883+ sysroot : & Utf8Path ,
884+ component : & Efi ,
885+ ) -> Result < ContentMetadata > {
886+ let ostreebootdir = sysroot. join ( ostreeutil:: BOOT_PREFIX ) ;
858887
859- let efi = ostreeboot_efi_path . join ( " EFI" ) ;
860- if !efi . exists ( ) {
861- return Ok ( ( ) ) ;
888+ // move EFI files to updates dir from /usr/lib/ostree-boot
889+ if !ostreebootdir . exists ( ) {
890+ anyhow :: bail! ( "Failed to find {ostreebootdir}" ) ;
862891 }
863- for entry in WalkDir :: new ( & efi) {
864- let entry = entry?;
865892
866- if entry. file_type ( ) . is_file ( ) {
867- let entry_path = entry. path ( ) ;
893+ let efisrc = ostreebootdir. join ( "efi/EFI" ) ;
894+ if !efisrc. exists ( ) {
895+ bail ! ( "Failed to find {:?}" , & efisrc) ;
896+ }
868897
869- // get path EFI/{BOOT,<vendor>}/<file>
870- let filepath = entry_path. strip_prefix ( & ostreeboot_efi_path) ?;
871- // get path /boot/efi/EFI/{BOOT,<vendor>}/<file>
872- let boot_filepath = Path :: new ( "/boot/efi" ) . join ( filepath) ;
898+ let dest_efidir = component_updatedir ( sysroot. as_str ( ) , component) ;
899+ let dest_efidir = Utf8PathBuf :: from_path_buf ( dest_efidir) . expect ( "Path is invalid UTF-8" ) ;
873900
874- // Run `rpm -qf <filepath>`
875- let pkg = crate :: packagesystem :: query_file (
876- sysroot . to_str ( ) . unwrap ( ) ,
877- boot_filepath . to_str ( ) . unwrap ( ) ,
878- ) ?;
901+ // Fork off mv() because on overlayfs one can't rename() a lower level
902+ // directory today, and this will handle the copy fallback.
903+ Command :: new ( "mv" )
904+ . args ( [ & efisrc , & dest_efidir ] )
905+ . run_capture_stderr ( ) ?;
879906
880- let ( name, evr) = pkg. split_once ( ' ' ) . unwrap ( ) ;
881- let component = name. split ( '-' ) . next ( ) . unwrap_or ( "" ) ;
882- // get path usr/lib/efi/<component>/<evr>
883- let efilib_path = Path :: new ( EFILIB ) . join ( component) . join ( evr) ;
907+ let efidir = openat:: Dir :: open ( dest_efidir. as_std_path ( ) )
908+ . with_context ( || format ! ( "Opening {}" , dest_efidir) ) ?;
884909
885- let sysroot_dir = openat:: Dir :: open ( sysroot) ?;
886- // Ensure dest parent directory exists
887- if let Some ( parent) = efilib_path. join ( filepath) . parent ( ) {
888- sysroot_dir. ensure_dir_all ( parent, 0o755 ) ?;
889- }
910+ let files = crate :: util:: filenames ( & efidir) ?. into_iter ( ) . map ( |mut f| {
911+ f. insert_str ( 0 , "/boot/efi/EFI" ) ;
912+ f
913+ } ) ;
890914
891- // Source dir is usr/lib/ostree-boot/efi
892- let src = sysroot_dir
893- . sub_dir ( & ostreeboot_efi)
894- . context ( "Opening ostree-boot dir" ) ?;
895- // Dest dir is usr/lib/efi/<component>/<evr>
896- let dest = sysroot_dir
897- . sub_dir ( & efilib_path)
898- . context ( "Opening usr/lib/efi dir" ) ?;
899- // Copy file from ostree-boot to usr/lib/efi
900- src. copy_file_at ( filepath, & dest, filepath)
901- . context ( "Copying file to usr/lib/efi" ) ?;
902- }
903- }
904- Ok ( ( ) )
915+ let files = files. collect :: < Vec < _ > > ( ) ;
916+
917+ query_files ( sysroot. as_str ( ) , files)
905918}
906919
907920#[ cfg( test) ]
0 commit comments