@@ -513,7 +513,12 @@ impl Redfish for Bmc {
513513 }
514514
515515 async fn boot_first ( & self , target : Boot ) -> Result < ( ) , RedfishError > {
516- self . s . boot_first ( target) . await
516+ let alias = match target {
517+ Boot :: Pxe => "Pxe" ,
518+ Boot :: HardDisk => "Hdd" ,
519+ Boot :: UefiHttp => "UefiHttp" ,
520+ } ;
521+ self . set_boot_order ( alias) . await
517522 }
518523
519524 /// AMI BMC requires If-Match header for boot order changes
@@ -738,23 +743,7 @@ impl Redfish for Bmc {
738743 mac_address : & str ,
739744 ) -> Result < Option < String > , RedfishError > {
740745 let mac = mac_address. to_uppercase ( ) ;
741- let system = self . get_system ( ) . await ?;
742-
743- let boot_options_id =
744- system
745- . boot
746- . boot_options
747- . clone ( )
748- . ok_or_else ( || RedfishError :: MissingKey {
749- key : "boot.boot_options" . to_string ( ) ,
750- url : system. odata . odata_id . clone ( ) ,
751- } ) ?;
752-
753- let all_boot_options: Vec < BootOption > = self
754- . get_collection ( boot_options_id)
755- . await
756- . and_then ( |c| c. try_get :: < BootOption > ( ) ) ?
757- . members ;
746+ let ( system, all_boot_options) = self . get_system_and_boot_options ( ) . await ?;
758747
759748 let target = all_boot_options. iter ( ) . find ( |opt| {
760749 let display = opt. display_name . to_uppercase ( ) ;
@@ -970,19 +959,10 @@ impl Bmc {
970959 self . s . client . patch_with_if_match ( & url, data) . await
971960 }
972961
973- /// Get expected and actual first boot option for checking boot order setup.
974- ///
975- /// AMI boot option format example:
976- /// DisplayName: "[Slot2]UEFI: HTTP IPv4 Nvidia Network Adapter - B8:E9:24:17:6D:72 P1"
977- /// BootOptionReference: "Boot0001"
978- ///
979- async fn get_expected_and_actual_first_boot_option (
962+ async fn get_system_and_boot_options (
980963 & self ,
981- boot_interface_mac : & str ,
982- ) -> Result < ( Option < String > , Option < String > ) , RedfishError > {
983- let mac = boot_interface_mac. to_uppercase ( ) ;
964+ ) -> Result < ( ComputerSystem , Vec < BootOption > ) , RedfishError > {
984965 let system = self . get_system ( ) . await ?;
985-
986966 let boot_options_id =
987967 system
988968 . boot
@@ -992,14 +972,68 @@ impl Bmc {
992972 key : "boot.boot_options" . to_string ( ) ,
993973 url : system. odata . odata_id . clone ( ) ,
994974 } ) ?;
995-
996975 let all_boot_options: Vec < BootOption > = self
997976 . get_collection ( boot_options_id)
998977 . await
999978 . and_then ( |c| c. try_get :: < BootOption > ( ) ) ?
1000979 . members ;
980+ Ok ( ( system, all_boot_options) )
981+ }
982+
983+ /// Finds the first boot option matching the given alias and moves it to the front
984+ /// of the boot order.
985+ async fn set_boot_order ( & self , alias : & str ) -> Result < ( ) , RedfishError > {
986+ let ( system, all_boot_options) = self . get_system_and_boot_options ( ) . await ?;
987+
988+ let target = all_boot_options
989+ . iter ( )
990+ . find ( |opt| opt. alias . as_deref ( ) == Some ( alias) ) ;
991+
992+ let target_ref = target
993+ . ok_or_else ( || {
994+ let all_names: Vec < _ > = all_boot_options
995+ . iter ( )
996+ . map ( |b| {
997+ format ! (
998+ "{}: {} (alias={})" ,
999+ b. boot_option_reference,
1000+ b. display_name,
1001+ b. alias. as_deref( ) . unwrap_or( "none" )
1002+ )
1003+ } )
1004+ . collect ( ) ;
1005+ RedfishError :: MissingBootOption ( format ! (
1006+ "No boot option with alias {:?} found; available: {:#?}" ,
1007+ alias, all_names
1008+ ) )
1009+ } ) ?
1010+ . boot_option_reference
1011+ . clone ( ) ;
1012+
1013+ let mut boot_order = system. boot . boot_order ;
1014+
1015+ if boot_order. first ( ) == Some ( & target_ref) {
1016+ return Ok ( ( ) ) ;
1017+ }
1018+
1019+ boot_order. retain ( |id| id != & target_ref) ;
1020+ boot_order. insert ( 0 , target_ref) ;
1021+ self . change_boot_order ( boot_order) . await
1022+ }
1023+
1024+ /// Get expected and actual first boot option for checking boot order setup.
1025+ ///
1026+ /// AMI boot option format example:
1027+ /// DisplayName: "[Slot2]UEFI: HTTP IPv4 Nvidia Network Adapter - B8:E9:24:17:6D:72 P1"
1028+ /// BootOptionReference: "Boot0001"
1029+ ///
1030+ async fn get_expected_and_actual_first_boot_option (
1031+ & self ,
1032+ boot_interface_mac : & str ,
1033+ ) -> Result < ( Option < String > , Option < String > ) , RedfishError > {
1034+ let mac = boot_interface_mac. to_uppercase ( ) ;
1035+ let ( system, all_boot_options) = self . get_system_and_boot_options ( ) . await ?;
10011036
1002- // Find expected boot option display name (HTTP IPv4 with matching MAC)
10031037 let expected_first_boot_option = all_boot_options
10041038 . iter ( )
10051039 . find ( |opt| {
0 commit comments