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