@@ -1540,15 +1540,18 @@ pub(crate) fn setup_composefs_bls_boot(
15401540 id : & Sha256HashValue ,
15411541 entry : BootEntry < Sha256HashValue > ,
15421542) -> Result < ( ) > {
1543- let ( root_path, cmdline_refs) = match setup_type {
1544- BootSetupType :: Setup ( root_setup) => {
1543+ let ( root_path, cmdline_refs, entry_id) = match setup_type {
1544+ BootSetupType :: Setup ( root_setup) => (
1545+ root_setup. physical_root_path . clone ( ) ,
15451546 // root_setup.kargs has [root=UUID=<UUID>, "rw"]
1546- ( root_setup. physical_root_path . clone ( ) , & root_setup. kargs )
1547- }
1547+ & root_setup. kargs ,
1548+ format ! ( "{}" , id. to_hex( ) ) ,
1549+ ) ,
15481550
15491551 BootSetupType :: Upgrade => (
15501552 Utf8PathBuf :: from ( "/sysroot" ) ,
15511553 & vec ! [ format!( "root=UUID={DPS_UUID}" ) , RW_KARG . to_string( ) ] ,
1554+ format ! ( "{}.staged" , id. to_hex( ) ) ,
15521555 ) ,
15531556 } ;
15541557
@@ -1564,7 +1567,7 @@ pub(crate) fn setup_composefs_bls_boot(
15641567 false ,
15651568 root_path. as_std_path ( ) ,
15661569 Some ( "boot" ) ,
1567- Some ( & id . to_hex ( ) ) ,
1570+ Some ( & entry_id ) ,
15681571 & str_slice,
15691572 )
15701573}
@@ -1580,6 +1583,24 @@ pub fn get_esp_partition(device: &str) -> Result<(String, Option<String>)> {
15801583 Ok ( ( esp. node , esp. uuid ) )
15811584}
15821585
1586+ fn get_user_config ( uki_id : & str ) -> String {
1587+ let s = format ! (
1588+ r#"
1589+ menuentry "Fedora Bootc UKI: ({uki_id})" {{
1590+ insmod fat
1591+ insmod chain
1592+ search --no-floppy --set=root --fs-uuid "${{EFI_PART_UUID}}"
1593+ chainloader /EFI/Linux/{uki_id}.efi
1594+ }}
1595+ "#
1596+ ) ;
1597+
1598+ return s;
1599+ }
1600+
1601+ /// Contains the EFP's filesystem UUID. Used by grub
1602+ const EFI_UUID_FILE : & str = "efiuuid.cfg" ;
1603+
15831604#[ context( "Setting up UKI boot" ) ]
15841605pub ( crate ) fn setup_composefs_uki_boot (
15851606 setup_type : BootSetupType ,
@@ -1650,66 +1671,63 @@ pub(crate) fn setup_composefs_uki_boot(
16501671
16511672 let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ) ;
16521673
1653- // Add the user grug cfg
1654- let grub_user_config = format ! (
1674+ let efi_uuid_source = format ! (
16551675 r#"
1656- menuentry "Fedora Bootc UKI: ({uki_id})" {{
1657- insmod fat
1658- insmod chain
1659- search --no-floppy --set=root --fs-uuid "${{EFI_PART_UUID}}"
1660- chainloader /EFI/Linux/{uki_id}.efi
1661- }}
1662- "# ,
1663- uki_id = id. to_hex( ) ,
1676+ if [ -f ${{config_directory}}/{EFI_UUID_FILE} ]; then
1677+ source ${{config_directory}}/{EFI_UUID_FILE}
1678+ fi
1679+ "#
16641680 ) ;
16651681
1666- let user_cfg_name = "grub2/user.cfg" ;
1682+ let user_cfg_name = if is_upgrade {
1683+ "grub2/user.cfg.staged"
1684+ } else {
1685+ "grub2/user.cfg"
1686+ } ;
16671687 let user_cfg_path = boot_dir. join ( user_cfg_name) ;
16681688
1669- // TODO: Figure out a better way to sort these menuentries. This is a bit scuffed
1670- //
1671- // Read the current user.cfg, split at the first menuentry, then stick the new menuentry in
1672- // between the efiuuid.cfg sourcing code and the previous menuentry
1689+ // Iterate over all available deployments, and generate a menuentry for each
16731690 if is_upgrade {
1674- let contents =
1675- std:: fs:: read_to_string ( & user_cfg_path) . context ( format ! ( "Reading {user_cfg_name}" ) ) ?;
1676-
16771691 let mut usr_cfg = std:: fs:: OpenOptions :: new ( )
16781692 . write ( true )
1679- . truncate ( true )
1693+ . create ( true )
16801694 . open ( user_cfg_path)
16811695 . with_context ( || format ! ( "Opening {user_cfg_name}" ) ) ?;
16821696
1683- let Some ( ( before, after) ) = contents. split_once ( "menuentry" ) else {
1684- anyhow:: bail!( "Did not find menuentry in {user_cfg_name}" )
1685- } ;
1697+ usr_cfg. write_all ( efi_uuid_source. as_bytes ( ) ) ?;
1698+ usr_cfg. write_all ( get_user_config ( & id. to_hex ( ) ) . as_bytes ( ) ) ?;
1699+
1700+ // root_path here will be /sysroot
1701+ for entry in std:: fs:: read_dir ( root_path. join ( STATE_DIR_RELATIVE ) ) ? {
1702+ let entry = entry?;
16861703
1687- usr_cfg
1688- . seek ( SeekFrom :: Start ( 0 ) )
1689- . with_context ( || format ! ( "Seek {user_cfg_name}" ) ) ? ;
1704+ let depl_file_name = entry . file_name ( ) ;
1705+ // SAFETY: Deployment file name shouldn't containg non UTF-8 chars
1706+ let depl_file_name = depl_file_name . to_string_lossy ( ) ;
16901707
1691- usr_cfg
1692- . write_all ( format ! ( "{before} {grub_user_config}\n menuentry {after}" ) . as_bytes ( ) )
1693- . with_context ( || format ! ( "Writing to {user_cfg_name}" ) ) ?;
1708+ usr_cfg. write_all ( get_user_config ( & depl_file_name) . as_bytes ( ) ) ?;
1709+ }
16941710
16951711 return Ok ( ( ) ) ;
16961712 }
16971713
1698- // Open grub2/efiuuid.cfg and write the EFI partition UUID in there
1714+ let efi_uuid_file_path = format ! ( "grub2/{EFI_UUID_FILE}" ) ;
1715+
1716+ // Open grub2/efiuuid.cfg and write the EFI partition fs-UUID in there
16991717 // This will be sourced by grub2/user.cfg to be used for `--fs-uuid`
17001718 let mut efi_uuid_file = std:: fs:: OpenOptions :: new ( )
17011719 . write ( true )
17021720 . create ( true )
1703- . open ( boot_dir. join ( "grub2/efiuuid.cfg" ) )
1704- . context ( "Opening grub2/efiuuid.cfg" ) ?;
1721+ . open ( boot_dir. join ( & efi_uuid_file_path ) )
1722+ . with_context ( || format ! ( "Opening {efi_uuid_file_path}" ) ) ?;
17051723
17061724 let esp_uuid = Task :: new ( "blkid for ESP UUID" , "blkid" )
17071725 . args ( [ "-s" , "UUID" , "-o" , "value" , & esp_device] )
17081726 . read ( ) ?;
17091727
17101728 efi_uuid_file
17111729 . write_all ( format ! ( "set EFI_PART_UUID=\" {}\" " , esp_uuid. trim( ) ) . as_bytes ( ) )
1712- . context ( "Writing to grub2/efiuuid.cfg" ) ?;
1730+ . with_context ( || format ! ( "Writing to {efi_uuid_file_path}" ) ) ?;
17131731
17141732 // Write to grub2/user.cfg
17151733 let mut usr_cfg = std:: fs:: OpenOptions :: new ( )
@@ -1718,15 +1736,8 @@ menuentry "Fedora Bootc UKI: ({uki_id})" {{
17181736 . open ( user_cfg_path)
17191737 . with_context ( || format ! ( "Opening {user_cfg_name}" ) ) ?;
17201738
1721- let efi_uuid_source = r#"
1722- if [ -f ${config_directory}/efiuuid.cfg ]; then
1723- source ${config_directory}/efiuuid.cfg
1724- fi
1725- "# ;
1726-
1727- usr_cfg
1728- . write_all ( format ! ( "{efi_uuid_source}\n {grub_user_config}" ) . as_bytes ( ) )
1729- . with_context ( || format ! ( "Writing to {user_cfg_name}" ) ) ?;
1739+ usr_cfg. write_all ( efi_uuid_source. as_bytes ( ) ) ?;
1740+ usr_cfg. write_all ( get_user_config ( & id. to_hex ( ) ) . as_bytes ( ) ) ?;
17301741
17311742 Ok ( ( ) )
17321743}
0 commit comments