@@ -26,8 +26,7 @@ use ostree_ext::tokio_util::spawn_blocking_cancellable_flatten;
2626use rustix:: fs:: { fsync, renameat_with, AtFlags , RenameFlags } ;
2727
2828use crate :: composefs_consts:: {
29- BOOT_LOADER_ENTRIES , ROLLBACK_BOOT_LOADER_ENTRIES , USER_CFG ,
30- USER_CFG_ROLLBACK ,
29+ BOOT_LOADER_ENTRIES , ROLLBACK_BOOT_LOADER_ENTRIES , USER_CFG , USER_CFG_ROLLBACK ,
3130} ;
3231use crate :: install:: { get_efi_uuid_source, BootType } ;
3332use crate :: parsers:: bls_config:: { parse_bls_config, BLSConfig } ;
@@ -1189,6 +1188,8 @@ pub(crate) fn fixup_etc_fstab(root: &Dir) -> Result<()> {
11891188
11901189#[ cfg( test) ]
11911190mod tests {
1191+ use crate :: parsers:: grub_menuconfig:: MenuentryBody ;
1192+
11921193 use super :: * ;
11931194
11941195 #[ test]
@@ -1283,4 +1284,117 @@ UUID=6907-17CA /boot/efi vfat umask=0077,shortname=win
12831284 assert_eq ! ( tempdir. read_to_string( "etc/fstab" ) ?, modified) ;
12841285 Ok ( ( ) )
12851286 }
1287+
1288+ #[ test]
1289+ fn test_sorted_bls_boot_entries ( ) -> Result < ( ) > {
1290+ let tempdir = cap_std_ext:: cap_tempfile:: tempdir ( cap_std:: ambient_authority ( ) ) ?;
1291+
1292+ let entry1 = r#"
1293+ title Fedora 42.20250623.3.1 (CoreOS)
1294+ version fedora-42.0
1295+ sort-key 1
1296+ linux /boot/7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6/vmlinuz-5.14.10
1297+ initrd /boot/7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6/initramfs-5.14.10.img
1298+ options root=UUID=abc123 rw composefs=7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6
1299+ "# ;
1300+
1301+ let entry2 = r#"
1302+ title Fedora 41.20250214.2.0 (CoreOS)
1303+ version fedora-42.0
1304+ sort-key 2
1305+ linux /boot/febdf62805de2ae7b6b597f2a9775d9c8a753ba1e5f09298fc8fbe0b0d13bf01/vmlinuz-5.14.10
1306+ initrd /boot/febdf62805de2ae7b6b597f2a9775d9c8a753ba1e5f09298fc8fbe0b0d13bf01/initramfs-5.14.10.img
1307+ options root=UUID=abc123 rw composefs=febdf62805de2ae7b6b597f2a9775d9c8a753ba1e5f09298fc8fbe0b0d13bf01
1308+ "# ;
1309+
1310+ tempdir. create_dir_all ( "loader/entries" ) ?;
1311+ tempdir. atomic_write (
1312+ "loader/entries/random_file.txt" ,
1313+ "Random file that we won't parse" ,
1314+ ) ?;
1315+ tempdir. atomic_write ( "loader/entries/entry1.conf" , entry1) ?;
1316+ tempdir. atomic_write ( "loader/entries/entry2.conf" , entry2) ?;
1317+
1318+ let result = get_sorted_bls_boot_entries ( & tempdir, true ) . unwrap ( ) ;
1319+
1320+ let mut config1 = BLSConfig :: default ( ) ;
1321+ config1. title = Some ( "Fedora 42.20250623.3.1 (CoreOS)" . into ( ) ) ;
1322+ config1. sort_key = Some ( "1" . into ( ) ) ;
1323+ config1. linux = "/boot/7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6/vmlinuz-5.14.10" . into ( ) ;
1324+ config1. initrd = vec ! [ "/boot/7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6/initramfs-5.14.10.img" . into( ) ] ;
1325+ config1. options = Some ( "root=UUID=abc123 rw composefs=7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6" . into ( ) ) ;
1326+
1327+ let mut config2 = BLSConfig :: default ( ) ;
1328+ config2. title = Some ( "Fedora 41.20250214.2.0 (CoreOS)" . into ( ) ) ;
1329+ config2. sort_key = Some ( "2" . into ( ) ) ;
1330+ config2. linux = "/boot/febdf62805de2ae7b6b597f2a9775d9c8a753ba1e5f09298fc8fbe0b0d13bf01/vmlinuz-5.14.10" . into ( ) ;
1331+ config2. initrd = vec ! [ "/boot/febdf62805de2ae7b6b597f2a9775d9c8a753ba1e5f09298fc8fbe0b0d13bf01/initramfs-5.14.10.img" . into( ) ] ;
1332+ config2. options = Some ( "root=UUID=abc123 rw composefs=febdf62805de2ae7b6b597f2a9775d9c8a753ba1e5f09298fc8fbe0b0d13bf01" . into ( ) ) ;
1333+
1334+ assert_eq ! ( result[ 0 ] . sort_key. as_ref( ) . unwrap( ) , "1" ) ;
1335+ assert_eq ! ( result[ 1 ] . sort_key. as_ref( ) . unwrap( ) , "2" ) ;
1336+
1337+ let result = get_sorted_bls_boot_entries ( & tempdir, false ) . unwrap ( ) ;
1338+ assert_eq ! ( result[ 0 ] . sort_key. as_ref( ) . unwrap( ) , "2" ) ;
1339+ assert_eq ! ( result[ 1 ] . sort_key. as_ref( ) . unwrap( ) , "1" ) ;
1340+
1341+ Ok ( ( ) )
1342+ }
1343+
1344+ #[ test]
1345+ fn test_sorted_uki_boot_entries ( ) -> Result < ( ) > {
1346+ let user_cfg = r#"
1347+ if [ -f ${config_directory}/efiuuid.cfg ]; then
1348+ source ${config_directory}/efiuuid.cfg
1349+ fi
1350+
1351+ menuentry "Fedora Bootc UKI: (f7415d75017a12a387a39d2281e033a288fc15775108250ef70a01dcadb93346)" {
1352+ insmod fat
1353+ insmod chain
1354+ search --no-floppy --set=root --fs-uuid "${EFI_PART_UUID}"
1355+ chainloader /EFI/Linux/f7415d75017a12a387a39d2281e033a288fc15775108250ef70a01dcadb93346.efi
1356+ }
1357+
1358+ menuentry "Fedora Bootc UKI: (7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6)" {
1359+ insmod fat
1360+ insmod chain
1361+ search --no-floppy --set=root --fs-uuid "${EFI_PART_UUID}"
1362+ chainloader /EFI/Linux/7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6.efi
1363+ }
1364+ "# ;
1365+
1366+ let bootdir = cap_std_ext:: cap_tempfile:: tempdir ( cap_std:: ambient_authority ( ) ) ?;
1367+ bootdir. create_dir_all ( format ! ( "grub2" ) ) ?;
1368+ bootdir. atomic_write ( format ! ( "grub2/{USER_CFG}" ) , user_cfg) ?;
1369+
1370+ let mut s = String :: new ( ) ;
1371+ let result = get_sorted_uki_boot_entries ( & bootdir, & mut s) ?;
1372+
1373+ let expected = vec ! [
1374+ MenuEntry {
1375+ title: "Fedora Bootc UKI: (f7415d75017a12a387a39d2281e033a288fc15775108250ef70a01dcadb93346)" . into( ) ,
1376+ body: MenuentryBody {
1377+ insmod: vec![ "fat" , "chain" ] ,
1378+ chainloader: "/EFI/Linux/f7415d75017a12a387a39d2281e033a288fc15775108250ef70a01dcadb93346.efi" . into( ) ,
1379+ search: "--no-floppy --set=root --fs-uuid \" ${EFI_PART_UUID}\" " ,
1380+ version: 0 ,
1381+ extra: vec![ ] ,
1382+ } ,
1383+ } ,
1384+ MenuEntry {
1385+ title: "Fedora Bootc UKI: (7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6)" . into( ) ,
1386+ body: MenuentryBody {
1387+ insmod: vec![ "fat" , "chain" ] ,
1388+ chainloader: "/EFI/Linux/7e11ac46e3e022053e7226a20104ac656bf72d1a84e3a398b7cce70e9df188b6.efi" . into( ) ,
1389+ search: "--no-floppy --set=root --fs-uuid \" ${EFI_PART_UUID}\" " ,
1390+ version: 0 ,
1391+ extra: vec![ ] ,
1392+ } ,
1393+ } ,
1394+ ] ;
1395+
1396+ assert_eq ! ( result, expected) ;
1397+
1398+ Ok ( ( ) )
1399+ }
12861400}
0 commit comments