@@ -18,7 +18,7 @@ use std::fs::create_dir_all;
1818use std:: io:: Write ;
1919use std:: os:: fd:: { AsFd , AsRawFd } ;
2020use std:: os:: unix:: process:: CommandExt ;
21- use std:: path:: Path ;
21+ use std:: path:: { Path , PathBuf } ;
2222use std:: process:: Command ;
2323use std:: str:: FromStr ;
2424use std:: sync:: Arc ;
@@ -108,6 +108,10 @@ const DEFAULT_REPO_CONFIG: &[(&str, &str)] = &[
108108/// Kernel argument used to specify we want the rootfs mounted read-write by default
109109const RW_KARG : & str = "rw" ;
110110
111+ /// The ESP partition label on Fedora CoreOS derivatives
112+ const COREOS_ESP_PART_LABEL : & str = "EFI-SYSTEM" ;
113+ const ANACONDA_ESP_PART_LABEL : & str = "EFI\\ x20System\\ x20Partition" ;
114+
111115#[ derive( clap:: Args , Debug , Clone , Serialize , Deserialize , PartialEq , Eq ) ]
112116pub ( crate ) struct InstallTargetOpts {
113117 // TODO: A size specifier which allocates free space for the root in *addition* to the base container image size
@@ -1533,6 +1537,44 @@ fn setup_composefs_bls_boot(
15331537 Ok ( ( ) )
15341538}
15351539
1540+ fn get_esp_device ( ) -> Option < PathBuf > {
1541+ let esp_devices = [ COREOS_ESP_PART_LABEL , ANACONDA_ESP_PART_LABEL ]
1542+ . into_iter ( )
1543+ . map ( |p| Path :: new ( "/dev/disk/by-partlabel/" ) . join ( p) ) ;
1544+ let mut esp_device = None ;
1545+ for path in esp_devices {
1546+ if path. exists ( ) {
1547+ esp_device = Some ( path) ;
1548+ break ;
1549+ }
1550+ }
1551+ return esp_device;
1552+ }
1553+
1554+ /// esp_device - /dev/disk/by-partlabel/<ESP_DEVICE>
1555+ fn get_esp_uuid ( esp_device : & PathBuf ) -> Result < String > {
1556+ // not using blkid here as the output might change from under us
1557+ let resolved = std:: fs:: canonicalize ( esp_device)
1558+ . with_context ( || format ! ( "Failed to resolve link {esp_device:?}" ) ) ?;
1559+
1560+ let mut uuid = String :: new ( ) ;
1561+
1562+ for dir_entry in std:: fs:: read_dir ( "/dev/disk/by-uuid" ) ? {
1563+ let file = dir_entry?;
1564+
1565+ let uuid_resolve = std:: fs:: canonicalize ( file. path ( ) )
1566+ . with_context ( || format ! ( "Failed to resolve link {file:?}" ) ) ?;
1567+
1568+ if resolved == uuid_resolve {
1569+ // SAFETY: UUID has to be [A-Fa-f0-9\-]
1570+ uuid = file. file_name ( ) . to_string_lossy ( ) . into_owned ( ) ;
1571+ break ;
1572+ }
1573+ }
1574+
1575+ Ok ( uuid)
1576+ }
1577+
15361578#[ context( "Setting up UKI boot" ) ]
15371579fn setup_composefs_uki_boot (
15381580 root_setup : & RootSetup ,
@@ -1541,35 +1583,47 @@ fn setup_composefs_uki_boot(
15411583 id : & Sha256HashValue ,
15421584 entry : BootEntry < Sha256HashValue > ,
15431585) -> Result < ( ) > {
1544- let rootfs_uuid = match & root_setup . rootfs_uuid {
1545- Some ( u ) => u ,
1546- None => anyhow:: bail!( "Expected rootfs to have a UUID by now" ) ,
1586+ // Write the UKI to <ESP>/EFI/Linux
1587+ let Some ( esp_device ) = get_esp_device ( ) else {
1588+ anyhow:: bail!( "ESP device not found" ) ;
15471589 } ;
15481590
1549- let boot_dir = root_setup. physical_root_path . join ( "boot" ) ;
1550- create_dir_all ( & boot_dir) . context ( "Failed to create boot dir" ) ?;
1591+ let mounted_esp: PathBuf = root_setup. physical_root_path . join ( "../esp" ) . into ( ) ;
1592+ create_dir_all ( & mounted_esp) . context ( "Failed to create dir {mounted_esp:?}" ) ?;
1593+
1594+ Task :: new ( "Mounting ESP" , "mount" )
1595+ . args ( [ & esp_device, & mounted_esp. clone ( ) ] )
1596+ . run ( ) ?;
15511597
15521598 composefs_write_boot_simple (
15531599 & repo,
15541600 entry,
15551601 & id,
1556- boot_dir . as_std_path ( ) ,
1602+ & mounted_esp ,
15571603 None ,
15581604 Some ( & format ! ( "{}" , id. to_hex( ) ) ) ,
15591605 & [ ] ,
15601606 ) ?;
15611607
1608+ Task :: new ( "Unmounting ESP" , "umount" )
1609+ . arg ( mounted_esp)
1610+ . run ( ) ?;
1611+
1612+ let boot_dir = root_setup. physical_root_path . join ( "boot" ) ;
1613+ create_dir_all ( & boot_dir) . context ( "Failed to create boot dir" ) ?;
1614+
15621615 // Add the user grug cfg
15631616 let grub_user_config = format ! (
15641617 r#"
15651618menuentry "Fedora Bootc UKI" {{
15661619 insmod fat
15671620 insmod chain
1568- search --no-floppy --set=root --fs-uuid {rootfs_uuid }
1569- chainloader /boot/ EFI/Linux/{uki_id}.efi
1621+ search --no-floppy --set=root --fs-uuid {esp_uuid }
1622+ chainloader /EFI/Linux/{uki_id}.efi
15701623}}
15711624"# ,
1572- uki_id = id. to_hex( )
1625+ uki_id = id. to_hex( ) ,
1626+ esp_uuid = get_esp_uuid( & esp_device) ?
15731627 ) ;
15741628
15751629 std:: fs:: write ( boot_dir. join ( "grub2/user.cfg" ) , grub_user_config)
0 commit comments