@@ -342,51 +342,81 @@ impl Component for Efi {
342342 dest_root : & str ,
343343 device : & str ,
344344 update_firmware : bool ,
345+ bootloader : crate :: bootupd:: Bootloader ,
345346 ) -> Result < InstalledContent > {
346- let Some ( meta) = get_component_update ( src_root, self ) ? else {
347- anyhow:: bail!( "No update metadata for component {} found" , self . name( ) ) ;
348- } ;
349- log:: debug!( "Found metadata {}" , meta. version) ;
350- let srcdir_name = component_updatedirname ( self ) ;
351- let ft = crate :: filetree:: FileTree :: new_from_dir ( & src_root. sub_dir ( & srcdir_name) ?) ?;
352-
353- // Let's attempt to use an already mounted ESP at the target
354- // dest_root if one is already mounted there in a known ESP location.
355- let destpath = if let Some ( destdir) = self . get_mounted_esp ( Path :: new ( dest_root) ) ? {
356- destdir
357- } else {
358- // Using `blockdev` to find the partition instead of partlabel because
359- // we know the target install toplevel device already.
347+ let esp_path = self . get_mounted_esp ( Path :: new ( dest_root) ) ?. or_else ( || {
360348 if device. is_empty ( ) {
361- anyhow:: bail!( "Device value not provided" ) ;
349+ None
350+ } else {
351+ let esp_device = blockdev:: get_esp_partition ( device) . ok ( ) . flatten ( ) ?;
352+ self . mount_esp_device ( Path :: new ( dest_root) , Path :: new ( & esp_device) )
353+ . ok ( )
362354 }
363- let esp_device = blockdev:: get_esp_partition ( device) ?
364- . ok_or_else ( || anyhow:: anyhow!( "Failed to find ESP device" ) ) ?;
365- self . mount_esp_device ( Path :: new ( dest_root) , Path :: new ( & esp_device) ) ?
366- } ;
355+ } ) ;
356+
357+ match bootloader {
358+ crate :: bootupd:: Bootloader :: SystemdBoot => {
359+ log:: info!( "Installing systemd-boot via bootctl" ) ;
360+ let esp_dir = openat:: Dir :: open ( esp_path. as_ref ( ) . ok_or_else ( || {
361+ anyhow:: anyhow!( "No ESP mount found for systemd-boot install" )
362+ } ) ?)
363+ . context ( "Opening mounted ESP directory for systemd-boot" ) ?;
364+ crate :: systemdbootconfigs:: install ( & esp_dir) ?;
365+ Ok ( InstalledContent {
366+ meta : ContentMetadata {
367+ timestamp : chrono:: Utc :: now ( ) ,
368+ version : "systemd-boot" . to_string ( ) ,
369+ } ,
370+ filetree : None ,
371+ adopted_from : None ,
372+ } )
373+ }
374+ crate :: bootupd:: Bootloader :: Grub | crate :: bootupd:: Bootloader :: _Auto => {
375+ let meta = match get_component_update ( src_root, self ) ? {
376+ Some ( meta) => meta,
377+ None => {
378+ log:: debug!(
379+ "No update metadata for component {} found, continuing (GRUB case)" ,
380+ self . name( )
381+ ) ;
382+ return Ok ( InstalledContent {
383+ meta : ContentMetadata {
384+ timestamp : chrono:: Utc :: now ( ) ,
385+ version : "grub" . to_string ( ) ,
386+ } ,
387+ filetree : None ,
388+ adopted_from : None ,
389+ } ) ;
390+ }
391+ } ;
392+ log:: debug!( "Found metadata {}" , meta. version) ;
393+ let srcdir_name = component_updatedirname ( self ) ;
394+ let ft = crate :: filetree:: FileTree :: new_from_dir ( & src_root. sub_dir ( & srcdir_name) ?) ?;
395+
396+ let destpath = esp_path
397+ . ok_or_else ( || anyhow:: anyhow!( "No ESP mount found for GRUB install" ) ) ?;
398+ let destd = & openat:: Dir :: open ( & destpath)
399+ . with_context ( || format ! ( "opening dest dir {}" , destpath. display( ) ) ) ?;
400+ validate_esp_fstype ( destd) ?;
367401
368- let destd = & openat:: Dir :: open ( & destpath)
369- . with_context ( || format ! ( "opening dest dir {}" , destpath. display( ) ) ) ?;
370- validate_esp_fstype ( destd) ?;
371-
372- // TODO - add some sort of API that allows directly setting the working
373- // directory to a file descriptor.
374- std:: process:: Command :: new ( "cp" )
375- . args ( [ "-rp" , "--reflink=auto" ] )
376- . arg ( & srcdir_name)
377- . arg ( destpath)
378- . current_dir ( format ! ( "/proc/self/fd/{}" , src_root. as_raw_fd( ) ) )
379- . run ( ) ?;
380- if update_firmware {
381- if let Some ( vendordir) = self . get_efi_vendor ( & src_root) ? {
382- self . update_firmware ( device, destd, & vendordir) ?
402+ std:: process:: Command :: new ( "cp" )
403+ . args ( [ "-rp" , "--reflink=auto" ] )
404+ . arg ( & srcdir_name)
405+ . arg ( & destpath)
406+ . current_dir ( format ! ( "/proc/self/fd/{}" , src_root. as_raw_fd( ) ) )
407+ . run ( ) ?;
408+ if update_firmware {
409+ if let Some ( vendordir) = self . get_efi_vendor ( & src_root) ? {
410+ self . update_firmware ( device, destd, & vendordir) ?
411+ }
412+ }
413+ Ok ( InstalledContent {
414+ meta,
415+ filetree : Some ( ft) ,
416+ adopted_from : None ,
417+ } )
383418 }
384419 }
385- Ok ( InstalledContent {
386- meta,
387- filetree : Some ( ft) ,
388- adopted_from : None ,
389- } )
390420 }
391421
392422 fn run_update (
0 commit comments