@@ -1531,15 +1531,18 @@ pub(crate) fn setup_composefs_bls_boot(
15311531 id : & Sha256HashValue ,
15321532 entry : BootEntry < Sha256HashValue > ,
15331533) -> Result < ( ) > {
1534- let ( root_path, cmdline_refs) = match setup_type {
1535- BootSetupType :: Setup ( root_setup) => {
1534+ let ( root_path, cmdline_refs, entry_id) = match setup_type {
1535+ BootSetupType :: Setup ( root_setup) => (
1536+ root_setup. physical_root_path . clone ( ) ,
15361537 // root_setup.kargs has [root=UUID=<UUID>, "rw"]
1537- ( root_setup. physical_root_path . clone ( ) , & root_setup. kargs )
1538- }
1538+ & root_setup. kargs ,
1539+ format ! ( "{}" , id. to_hex( ) ) ,
1540+ ) ,
15391541
15401542 BootSetupType :: Upgrade => (
15411543 Utf8PathBuf :: from ( "/sysroot" ) ,
15421544 & vec ! [ format!( "root=UUID={DPS_UUID}" ) , RW_KARG . to_string( ) ] ,
1545+ format ! ( "{}.staged" , id. to_hex( ) ) ,
15431546 ) ,
15441547 } ;
15451548
@@ -1555,7 +1558,7 @@ pub(crate) fn setup_composefs_bls_boot(
15551558 false ,
15561559 root_path. as_std_path ( ) ,
15571560 Some ( "boot" ) ,
1558- Some ( & id . to_hex ( ) ) ,
1561+ Some ( & entry_id ) ,
15591562 & str_slice,
15601563 )
15611564}
@@ -1571,6 +1574,24 @@ pub fn get_esp_partition(device: &str) -> Result<(String, Option<String>)> {
15711574 Ok ( ( esp. node , esp. uuid ) )
15721575}
15731576
1577+ fn get_user_config ( uki_id : & str ) -> String {
1578+ let s = format ! (
1579+ r#"
1580+ menuentry "Fedora Bootc UKI: ({uki_id})" {{
1581+ insmod fat
1582+ insmod chain
1583+ search --no-floppy --set=root --fs-uuid "${{EFI_PART_UUID}}"
1584+ chainloader /EFI/Linux/{uki_id}.efi
1585+ }}
1586+ "#
1587+ ) ;
1588+
1589+ return s;
1590+ }
1591+
1592+ /// Contains the EFP's filesystem UUID. Used by grub
1593+ const EFI_UUID_FILE : & str = "efiuuid.cfg" ;
1594+
15741595#[ context( "Setting up UKI boot" ) ]
15751596pub ( crate ) fn setup_composefs_uki_boot (
15761597 setup_type : BootSetupType ,
@@ -1641,66 +1662,63 @@ pub(crate) fn setup_composefs_uki_boot(
16411662
16421663 let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ) ;
16431664
1644- // Add the user grug cfg
1645- let grub_user_config = format ! (
1665+ let efi_uuid_source = format ! (
16461666 r#"
1647- menuentry "Fedora Bootc UKI: ({uki_id})" {{
1648- insmod fat
1649- insmod chain
1650- search --no-floppy --set=root --fs-uuid "${{EFI_PART_UUID}}"
1651- chainloader /EFI/Linux/{uki_id}.efi
1652- }}
1653- "# ,
1654- uki_id = id. to_hex( ) ,
1667+ if [ -f ${{config_directory}}/{EFI_UUID_FILE} ]; then
1668+ source ${{config_directory}}/{EFI_UUID_FILE}
1669+ fi
1670+ "#
16551671 ) ;
16561672
1657- let user_cfg_name = "grub2/user.cfg" ;
1673+ let user_cfg_name = if is_upgrade {
1674+ "grub2/user.cfg.staged"
1675+ } else {
1676+ "grub2/user.cfg"
1677+ } ;
16581678 let user_cfg_path = boot_dir. join ( user_cfg_name) ;
16591679
1660- // TODO: Figure out a better way to sort these menuentries. This is a bit scuffed
1661- //
1662- // Read the current user.cfg, split at the first menuentry, then stick the new menuentry in
1663- // between the efiuuid.cfg sourcing code and the previous menuentry
1680+ // Iterate over all available deployments, and generate a menuentry for each
16641681 if is_upgrade {
1665- let contents =
1666- std:: fs:: read_to_string ( & user_cfg_path) . context ( format ! ( "Reading {user_cfg_name}" ) ) ?;
1667-
16681682 let mut usr_cfg = std:: fs:: OpenOptions :: new ( )
16691683 . write ( true )
1670- . truncate ( true )
1684+ . create ( true )
16711685 . open ( user_cfg_path)
16721686 . with_context ( || format ! ( "Opening {user_cfg_name}" ) ) ?;
16731687
1674- let Some ( ( before, after) ) = contents. split_once ( "menuentry" ) else {
1675- anyhow:: bail!( "Did not find menuentry in {user_cfg_name}" )
1676- } ;
1688+ usr_cfg. write_all ( efi_uuid_source. as_bytes ( ) ) ?;
1689+ usr_cfg. write_all ( get_user_config ( & id. to_hex ( ) ) . as_bytes ( ) ) ?;
1690+
1691+ // root_path here will be /sysroot
1692+ for entry in std:: fs:: read_dir ( root_path. join ( STATE_DIR_RELATIVE ) ) ? {
1693+ let entry = entry?;
16771694
1678- usr_cfg
1679- . seek ( SeekFrom :: Start ( 0 ) )
1680- . with_context ( || format ! ( "Seek {user_cfg_name}" ) ) ? ;
1695+ let depl_file_name = entry . file_name ( ) ;
1696+ // SAFETY: Deployment file name shouldn't containg non UTF-8 chars
1697+ let depl_file_name = depl_file_name . to_string_lossy ( ) ;
16811698
1682- usr_cfg
1683- . write_all ( format ! ( "{before} {grub_user_config}\n menuentry {after}" ) . as_bytes ( ) )
1684- . with_context ( || format ! ( "Writing to {user_cfg_name}" ) ) ?;
1699+ usr_cfg. write_all ( get_user_config ( & depl_file_name) . as_bytes ( ) ) ?;
1700+ }
16851701
16861702 return Ok ( ( ) ) ;
16871703 }
16881704
1689- // Open grub2/efiuuid.cfg and write the EFI partition UUID in there
1705+ let efi_uuid_file_path = format ! ( "grub2/{EFI_UUID_FILE}" ) ;
1706+
1707+ // Open grub2/efiuuid.cfg and write the EFI partition fs-UUID in there
16901708 // This will be sourced by grub2/user.cfg to be used for `--fs-uuid`
16911709 let mut efi_uuid_file = std:: fs:: OpenOptions :: new ( )
16921710 . write ( true )
16931711 . create ( true )
1694- . open ( boot_dir. join ( "grub2/efiuuid.cfg" ) )
1695- . context ( "Opening grub2/efiuuid.cfg" ) ?;
1712+ . open ( boot_dir. join ( & efi_uuid_file_path ) )
1713+ . with_context ( || format ! ( "Opening {efi_uuid_file_path}" ) ) ?;
16961714
16971715 let esp_uuid = Task :: new ( "blkid for ESP UUID" , "blkid" )
16981716 . args ( [ "-s" , "UUID" , "-o" , "value" , & esp_device] )
16991717 . read ( ) ?;
17001718
17011719 efi_uuid_file
17021720 . write_all ( format ! ( "set EFI_PART_UUID=\" {}\" " , esp_uuid. trim( ) ) . as_bytes ( ) )
1703- . context ( "Writing to grub2/efiuuid.cfg" ) ?;
1721+ . with_context ( || format ! ( "Writing to {efi_uuid_file_path}" ) ) ?;
17041722
17051723 // Write to grub2/user.cfg
17061724 let mut usr_cfg = std:: fs:: OpenOptions :: new ( )
@@ -1709,15 +1727,8 @@ menuentry "Fedora Bootc UKI: ({uki_id})" {{
17091727 . open ( user_cfg_path)
17101728 . with_context ( || format ! ( "Opening {user_cfg_name}" ) ) ?;
17111729
1712- let efi_uuid_source = r#"
1713- if [ -f ${config_directory}/efiuuid.cfg ]; then
1714- source ${config_directory}/efiuuid.cfg
1715- fi
1716- "# ;
1717-
1718- usr_cfg
1719- . write_all ( format ! ( "{efi_uuid_source}\n {grub_user_config}" ) . as_bytes ( ) )
1720- . with_context ( || format ! ( "Writing to {user_cfg_name}" ) ) ?;
1730+ usr_cfg. write_all ( efi_uuid_source. as_bytes ( ) ) ?;
1731+ usr_cfg. write_all ( get_user_config ( & id. to_hex ( ) ) . as_bytes ( ) ) ?;
17211732
17221733 Ok ( ( ) )
17231734}
0 commit comments