From 989d0895b37dad347ef01d21d21814f5cee37877 Mon Sep 17 00:00:00 2001 From: bybai Date: Tue, 5 Dec 2017 01:12:56 -0500 Subject: [PATCH] enhance rflash stream --- xCAT-server/lib/xcat/plugins/openbmc.pm | 328 ++++++++++++++---------- 1 file changed, 195 insertions(+), 133 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index 52f03a717..080f68b4f 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -70,6 +70,9 @@ $::UPLOAD_WAIT_TOTALTIME = int($::UPLOAD_WAIT_ATTEMPT*$::UPLOAD_WAIT_INTERVAL $::RPOWER_CHECK_INTERVAL = 2; $::RPOWER_MAX_RETRY = 30; +$::BMC_MAX_RETRY = 20; +$::BMC_CHECK_INTERVAL = 15; + $::RSPCONFIG_DUMP_INTERVAL = 15; $::RSPCONFIG_DUMP_MAX_RETRY = 20; $::RSPCONFIG_DUMP_WAIT_TOTALTIME = int($::RSPCONFIG_DUMP_INTERVAL*$::RSPCONFIG_DUMP_MAX_RETRY); @@ -640,12 +643,16 @@ sub retry_after { #------------------------------------------------------- sub retry_check_times { - my ($node, $request_status, $check_type, $wait_time, $msg, $response_status) = @_; + my ($node, $request_status, $check_type, $wait_time, $response_status) = @_; if ($node_info{$node}{$check_type} > 0) { $node_info{$node}{$check_type}--; - my $retry_msg = "Retry BMC state, wait for seconds ..."; + if ($node_info{$node}{wait_start}) { + $node_info{$node}{wait_end} = time(); + } else { + $node_info{$node}{wait_start} = time(); + } + my $retry_msg = "Retry BMC state, wait for $wait_time seconds ..."; xCAT::MsgUtils->message("I", { data => ["$node: $retry_msg"] }, $callback); - if ($response_status ne $::RESPONSE_SERVICE_UNAVAILABLE) { my $login_url = "$http_protocol://$node_info{$node}{bmc}/login"; my $content = '[ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ]'; @@ -659,6 +666,8 @@ sub retry_check_times { $node_wait{$node} = time() + $wait_time; return; } else { + my $wait_time_X = $node_info{$node}{wait_end} - $node_info{$node}{wait_start}; + my $msg="Error: Sent bmcreboot but state did not change to BMC Ready after waiting $wait_time_X seconds. (State=BMC NotReady)."; xCAT::SvrUtils::sendmsg([1, $msg], $callback, $node); $node_info{$node}{cur_status} = ""; $wait_node_num--; @@ -1067,7 +1076,7 @@ sub parse_args { if ($option_flag =~ tr{ }{ } > 0) { unless ($verbose or $option_flag =~/^-d --no-host-reboot$/) { - return ([ 1, "These multiple options are not supported. Options specified: $option_flag"]); + return ([ 1, "Multiple options are not supported. Options specified: $option_flag"]); } } @@ -1093,8 +1102,15 @@ sub parse_args { $action = "delete"; } xCAT::SvrUtils::sendmsg("Attempting to $action ID=$flash_arguments[0], please wait...", $callback); - } - else { + } elsif ($filepath_passed) { + if ($option_flag !~ /^-d|^-d --no-host-reboot$/) { + return ([ 1, "Invalid option specified when an directory is provided: $option_flag" ]); + } + if (!opendir(DIR, $tarball_path)) { + return ([1, "Can't open directory : $tarball_path"]); + } + closedir(DIR); + } else { # Neither Filename nor updateid was not passed, check flags allowed without file or updateid if ($option_flag !~ /^-c$|^--check$|^-l$|^--list$/) { return ([ 1, "Invalid option specified with $option_flag: $invalid_options" ]); @@ -1456,6 +1472,10 @@ sub parse_command_status { } elsif ($subcommand =~ /-a|--activate/) { $activate = 1; } elsif ($subcommand =~ /-d/) { + my $check = unsupported($callback); if (ref($check) eq "ARRAY") { + xCAT::SvrUtils::sendmsg($check, $callback); + return 1; + } $streamline = 1; } elsif ($subcommand =~ /--no-host-reboot/) { $nohost_reboot = 1; @@ -1528,7 +1548,7 @@ sub parse_command_status { } elsif (opendir(DIR, $update_file)) { my @tar_files = readdir(DIR); foreach my $file (@tar_files) { - if ($file !~ /^obmc-phosphor-image-witherspoon.ubi.mtd.tar$|^witherspoon.pnor.squashfs.tar$/) { + if ($file !~ /.*\.tar$/) { next; } else { my $full_path_file = $update_file."/".$file; @@ -1537,24 +1557,26 @@ sub parse_command_status { my $purpose_version_in_file = `$grep_cmd $purpose_tag $full_path_file`; chomp($firmware_version_in_file); chomp($purpose_version_in_file); - (my $purpose_string,$purpose_value) = split("=", $purpose_version_in_file); - (my $version_string,$version_value) = split("=", $firmware_version_in_file); - if ($file =~ /^obmc-phosphor-image-witherspoon.ubi.mtd.tar$/){ - $::UPLOAD_FILE = $full_path_file; - $::UPLOAD_FILE_VERSION = $version_value; - } elsif ($file =~ /^witherspoon.pnor.squashfs.tar$/) { - $::UPLOAD_PNOR = $full_path_file; - $::UPLOAD_PNOR_VERSION = $version_value; + if (defined($firmware_version_in_file) and defined($purpose_version_in_file)) { + (my $purpose_string,$purpose_value) = split("=", $purpose_version_in_file); + (my $version_string,$version_value) = split("=", $firmware_version_in_file); + if ($purpose_value =~ /Purpose.BMC$/ and $version_string =~/version/){ + $::UPLOAD_FILE = $full_path_file; + $::UPLOAD_FILE_VERSION = $version_value; + } elsif ($purpose_value =~ /Purpose.Host$/ and $version_value =~ /witherspoon/) { + $::UPLOAD_PNOR = $full_path_file; + $::UPLOAD_PNOR_VERSION = $version_value; + } } } } my $return_code = 0; if (!$::UPLOAD_FILE) { - xCAT::SvrUtils::sendmsg([1,"no BMC tar ball found in $update_file"], $callback); + xCAT::SvrUtils::sendmsg([1,"No BMC tar file found in $update_file"], $callback); $return_code = 1; } if (!$::UPLOAD_PNOR) { - xCAT::SvrUtils::sendmsg([1,"no PNOR tar ball found in $update_file"], $callback); + xCAT::SvrUtils::sendmsg([1,"No PNOR tar file found in $update_file"], $callback); $return_code = 1; } if ($return_code) { @@ -1632,46 +1654,46 @@ sub parse_command_status { $next_status{"RFLASH_UPDATE_CHECK_ID_REQUEST"} = "RFLASH_UPDATE_CHECK_ID_RESPONSE"; $next_status{"RFLASH_UPDATE_CHECK_ID_RESPONSE"} = "RFLASH_UPDATE_ACTIVATE_REQUEST"; $next_status{"RFLASH_UPDATE_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_ACTIVATE_RESPONSE"; + $next_status{"RFLASH_UPDATE_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; + $next_status{"RFLASH_UPDATE_CHECK_STATE_REQUEST"} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE"; $next_status{"RFLASH_SET_PRIORITY_REQUEST"} = "RFLASH_SET_PRIORITY_RESPONSE"; $next_status{"RFLASH_SET_PRIORITY_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; } if ($::UPLOAD_ACTIVATE_STREAM) { $next_status{LOGIN_RESPONSE} = "RFLASH_FILE_UPLOAD_REQUEST"; - $next_status{"RFLASH_FILE_UPLOAD_REQUEST"} = "RFLASH_FILE_UPLOAD_RESPONSE"; - $next_status{"RFLASH_FILE_UPLOAD_RESPONSE"} = "RFLASH_UPDATE_CHECK_ID_REQUEST"; - $next_status{"RFLASH_UPDATE_CHECK_ID_REQUEST"} = "RFLASH_UPDATE_CHECK_ID_RESPONSE"; - $next_status{"RFLASH_UPDATE_CHECK_ID_RESPONSE"} = "RFLASH_UPDATE_ACTIVATE_REQUEST"; - $next_status{"RFLASH_UPDATE_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_ACTIVATE_RESPONSE"; - $next_status{"RFLASH_UPDATE_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_HOST_ACTIVATE_REQUEST"; - $next_status{"RFLASH_UPDATE_HOST_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE"; - $next_status{"RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; - $next_status{"RFLASH_UPDATE_CHECK_STATE_REQUEST"} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE"; - $next_status{"RFLASH_SET_PRIORITY_REQUEST"} = "RFLASH_SET_PRIORITY_RESPONSE"; - $next_status{"RFLASH_SET_PRIORITY_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; - $next_status{"RFLASH_UPDATE_CHECK_STATE_RESPONSE"} = "RPOWER_BMCREBOOT_REQUEST"; - $next_status{"RPOWER_BMCREBOOT_REQUEST"} = "RPOWER_RESET_RESPONSE"; + $next_status{RFLASH_FILE_UPLOAD_REQUEST} = "RFLASH_FILE_UPLOAD_RESPONSE"; + $next_status{RFLASH_FILE_UPLOAD_RESPONSE} = "RFLASH_UPDATE_CHECK_ID_REQUEST"; + $next_status{RFLASH_UPDATE_CHECK_ID_REQUEST} = "RFLASH_UPDATE_CHECK_ID_RESPONSE"; + $next_status{RFLASH_UPDATE_CHECK_ID_RESPONSE} = "RFLASH_UPDATE_ACTIVATE_REQUEST"; + $next_status{RFLASH_UPDATE_ACTIVATE_REQUEST} = "RFLASH_UPDATE_ACTIVATE_RESPONSE"; + $next_status{RFLASH_UPDATE_ACTIVATE_RESPONSE} = "RFLASH_UPDATE_HOST_ACTIVATE_REQUEST"; + $next_status{RFLASH_UPDATE_HOST_ACTIVATE_REQUEST} = "RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE"; + $next_status{RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; + $next_status{RFLASH_UPDATE_CHECK_STATE_REQUEST} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE"; + $next_status{RFLASH_SET_PRIORITY_REQUEST} = "RFLASH_SET_PRIORITY_RESPONSE"; + $next_status{RFLASH_SET_PRIORITY_RESPONSE} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; + $next_status{RFLASH_UPDATE_CHECK_STATE_REQUEST} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE"; + $next_status{RFLASH_UPDATE_CHECK_STATE_RESPONSE} = "RPOWER_BMCREBOOT_REQUEST"; + $next_status{RPOWER_BMCREBOOT_REQUEST} = "RPOWER_RESET_RESPONSE"; $status_info{RPOWER_RESET_RESPONSE}{argv} = "bmcreboot"; - $next_status{"RPOWER_RESET_RESPONSE"} = "RPOWER_BMC_CHECK_REQUEST"; - $next_status{"RPOWER_BMC_CHECK_REQUEST"} = "RPOWER_BMC_STATUS_RESPONSE"; - $next_status{"LOGIN_REQUEST_GENERAL"} = "LOGIN_RESPONSE_GENERAL"; - $next_status{"LOGIN_RESPONSE_GENERAL"} = "RPOWER_BMC_STATUS_REQUEST"; - $next_status{"RPOWER_BMC_STATUS_REQUEST"} = "RPOWER_BMC_STATUS_RESPONSE"; + $next_status{RPOWER_RESET_RESPONSE} = "RPOWER_BMC_CHECK_REQUEST"; + $next_status{RPOWER_BMC_CHECK_REQUEST} = "RPOWER_BMC_STATUS_RESPONSE"; + $next_status{LOGIN_REQUEST_GENERAL} = "LOGIN_RESPONSE_GENERAL"; + $next_status{LOGIN_RESPONSE_GENERAL} = "RPOWER_BMC_STATUS_REQUEST"; + $next_status{RPOWER_BMC_STATUS_REQUEST} = "RPOWER_BMC_STATUS_RESPONSE"; $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} = "bmcstate"; if (!$::RFLASH_STREAM_NO_HOST_REBOOT) { - $next_status{"RPOWER_BMC_STATUS_RESPONSE"} = "RPOWER_STATUS_REQUEST"; - $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; - $next_status{RPOWER_STATUS_RESPONSE}{ON} = "RPOWER_OFF_REQUEST"; - $next_status{RPOWER_OFF_REQUEST} = "RPOWER_OFF_RESPONSE"; - $next_status{RPOWER_OFF_RESPONSE} = "RPOWER_CHECK_REQUEST"; - $next_status{RPOWER_CHECK_REQUEST} = "RPOWER_CHECK_RESPONSE"; - $next_status{RPOWER_CHECK_RESPONSE}{ON} = "RPOWER_CHECK_REQUEST"; - $next_status{RPOWER_CHECK_RESPONSE}{OFF} = "RPOWER_ON_REQUEST"; - $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; - $status_info{RPOWER_ON_RESPONSE}{argv} = "reset"; + $next_status{RPOWER_BMC_STATUS_RESPONSE} = "RPOWER_OFF_REQUEST"; + $next_status{RPOWER_OFF_REQUEST} = "RPOWER_OFF_RESPONSE"; + $next_status{RPOWER_OFF_RESPONSE} = "RPOWER_CHECK_REQUEST"; + $next_status{RPOWER_CHECK_REQUEST} = "RPOWER_CHECK_RESPONSE"; + $next_status{RPOWER_CHECK_RESPONSE}{ON} = "RPOWER_CHECK_REQUEST"; + $next_status{RPOWER_CHECK_RESPONSE}{OFF} = "RPOWER_ON_REQUEST"; + $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; + $status_info{RPOWER_ON_RESPONSE}{argv} = "boot"; } } } - return; } @@ -1864,7 +1886,11 @@ sub gen_send_request { # Slightly different debug message when doing a file upload $debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -T $::UPLOAD_FILE $request_url"; } else { - $debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -d '$content' $request_url"; + if ($node_info{$node}{cur_status} eq "LOGIN_REQUEST_GENERAL") { + $debug_info = "curl -k -c cjar -H \"Content-Type: application/json\" -d '{ \"data\": [\"$node_info{$node}{username}\", \"xxxxxx\"] }' $request_url"; + } else { + $debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -d '$content' $request_url"; + } } } process_debug_info($node, $debug_info); @@ -1911,8 +1937,7 @@ sub deal_with_response { return; } if (defined $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} and $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} =~ /bmcstate$/) { - my $error_msg = "Sent reboot BMC but state did not change to BMCReady (State=BMC NotReady)."; - retry_check_times($node, "RPOWER_BMC_STATUS_REQUEST", "bmc_conn_check_times", $::BMC_CHECK_INTERVAL, $error_msg, $response->status_line); + retry_check_times($node, "RPOWER_BMC_STATUS_REQUEST", "bmc_conn_check_times", $::BMC_CHECK_INTERVAL, $response->status_line); return; } @@ -2169,7 +2194,7 @@ sub rpower_response { xCAT::SvrUtils::sendmsg("BMC $bmc_short_state", $callback, $node); } elsif ($node_info{$node}{cur_status} eq "RPOWER_BMC_STATUS_RESPONSE" and (defined $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv}) and $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} =~ /bmcstate$/) { my $bmc_short_state = (split(/\./, $bmc_state))[-1]; - if (defined($bmc_state) and $bmc_state ne "xyz.openbmc_project.State.BMC.BMCState.Ready") { + if (defined($bmc_state) and $bmc_state !~ /State.BMC.BMCState.Ready$/) { if ($node_info{$node}{bmcstate_check_times} > 0) { $node_info{$node}{bmcstate_check_times}--; if ($node_info{$node}{wait_start}) { @@ -3235,7 +3260,6 @@ sub rflash_response { my $update_version; my $rflash_log_file = xCAT::Utils->full_path($node.".log", RFLASH_LOG_DIR); open (RFLASH_LOG_FILE_HANDLE, ">> $rflash_log_file"); - if ($node_info{$node}{cur_status} eq "RFLASH_LIST_RESPONSE") { # Get the functional IDs to accurately mark the active running FW my $functional = get_functional_software_ids($response_info); @@ -3333,7 +3357,7 @@ sub rflash_response { } } } - if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE") { + if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE" or $node_info{$node}{cur_status} eq "RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE") { my $flash_started_msg = "rflash started, please wait..."; if ($::VERBOSE) { xCAT::SvrUtils::sendmsg("$flash_started_msg", $callback, $node); @@ -3347,20 +3371,22 @@ sub rflash_response { my %activation_state; my %progress_state; my %priority_state; + my %update_ids; my $update_res=0; my $version; foreach my $key_url (keys %{$response_info->{data}}) { - if ($::UPLOAD_ACTIVATE_STREAM) { + if ($::UPLOAD_ACTIVATE_STREAM or $::UPLOAD_AND_ACTIVATE) { my %content = %{${$response_info->{data}}{$key_url}}; $version = $content{Version}; if (defined($version)) { if ($version ne $::UPLOAD_FILE_VERSION and $version ne $::UPLOAD_PNOR_VERSION) { next; - } + } # Get values of some attributes to determine activation status $activation_state{$version} = $content{Activation}; $progress_state{$version} = $content{Progress}; $priority_state{$version} = $content{Priority}; + $update_ids{$version} = (split(/\//, $key_url))[ -1 ]; } } else { # This is for -a option @@ -3377,56 +3403,68 @@ sub rflash_response { } } my $firm_msg; + my $version_num = 0; + my $rsp; + my $length = keys %activation_state; foreach my $firm_version (keys %activation_state) { if ($firm_version eq "default") { $firm_msg = "Firmware"; } else { $firm_msg = "Firmware $firm_version"; } - if ($activation_state{$firm_version} =~ /Software.Activation.Activations.Failed/) { - # Activation failed. Report error and exit - my $flash_failed_msg = "Firmware activation failed."; - xCAT::SvrUtils::sendmsg([1,"$flash_failed_msg"], $callback, $node); - print RFLASH_LOG_FILE_HANDLE "$flash_failed_msg\n"; - close (RFLASH_LOG_FILE_HANDLE); - $node_info{$node}{rst} = "$flash_failed_msg"; - $wait_node_num--; - return; - } - elsif ($activation_state{$firm_version} =~ /Software.Activation.Activations.Active/) { - if (scalar($priority_state{$firm_version}) == 0) { - # Activation state of active and priority of 0 indicates the activation has been completed - my $flash_success_msg = "Firmware activation successful."; - xCAT::SvrUtils::sendmsg("$flash_success_msg", $callback, $node); - print RFLASH_LOG_FILE_HANDLE "$flash_success_msg\n"; + if ($activation_state{$firm_version} =~ /Software.Activation.Activations.Failed/) { + # Activation failed. Report error and exit + my $flash_failed_msg = "$firm_msg activation failed."; + xCAT::SvrUtils::sendmsg([1,"$flash_failed_msg"], $callback, $node); + $update_res = 1; + print RFLASH_LOG_FILE_HANDLE "$flash_failed_msg\n"; close (RFLASH_LOG_FILE_HANDLE); - $node_info{$node}{rst} = "$flash_success_msg"; - $wait_node_num--; + $node_info{$node}{rst} = "$flash_failed_msg"; + } elsif ($activation_state{$firm_version} =~ /Software.Activation.Activations.Active/) { + if (scalar($priority_state{$firm_version}) == 0) { + $version_num ++; + my $flash_success_msg = "$node: $firm_msg activation successful."; + push @{ $rsp->{data} },$flash_success_msg; + # Activation state of active and priority of 0 indicates the activation has been completed + if ( $length == $version_num ) { + xCAT::MsgUtils->message("I", $rsp, $callback) if ($rsp); + print RFLASH_LOG_FILE_HANDLE "$flash_success_msg\n"; + $node_info{$node}{rst} = "$flash_success_msg"; + if (!$::UPLOAD_ACTIVATE_STREAM) { + $wait_node_num--; + return; + } + else{ + $next_status{ $node_info{$node}{cur_status} } = "RPOWER_BMCREBOOT_REQUEST"; + } + } + } else { + # Activation state of active and priority of non 0 - need to just set priority to 0 to activate + print "$firm_version update is already active, just need to set priority to 0\n"; + if ($::UPLOAD_ACTIVATE_STREAM) { + $status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} = + $::SOFTWARE_URL . "/$update_ids{$firm_version}/attr/Priority"; + } + $next_status{ $node_info{$node}{cur_status} } = "RFLASH_SET_PRIORITY_REQUEST"; + } + } elsif ($activation_state{$firm_version} =~ /Software.Activation.Activations.Activating/) { + my $activating_progress_msg = "Activating $firm_msg... $progress_state{$firm_version}\%"; + if ($::VERBOSE) { + xCAT::SvrUtils::sendmsg("$activating_progress_msg", $callback, $node); + } + print RFLASH_LOG_FILE_HANDLE "$activating_progress_msg\n"; + close (RFLASH_LOG_FILE_HANDLE); + # Activation still going, sleep for a bit, then print the progress value + # Set next state to come back here to chect the activation status again. + retry_after($node, "RFLASH_UPDATE_CHECK_STATE_REQUEST", 15); return; } - else { - # Activation state of active and priority of non 0 - need to just set priority to 0 to activate - print "Update is already active, just need to set priority to 0\n"; - $next_status{ $node_info{$node}{cur_status} } = "RFLASH_SET_PRIORITY_REQUEST"; - } - } - elsif ($activation_state =~ /Software.Activation.Activations.Activating/) { - my $activating_progress_msg = "Activating firmware... $progress_state\%"; - if ($::VERBOSE) { - xCAT::SvrUtils::sendmsg("$activating_progress_msg", $callback, $node); - } - print RFLASH_LOG_FILE_HANDLE "$activating_progress_msg\n"; - close (RFLASH_LOG_FILE_HANDLE); - # Activation still going, sleep for a bit, then print the progress value - # Set next state to come back here to chect the activation status again. - retry_after($node, "RFLASH_UPDATE_CHECK_STATE_REQUEST", 15); - return; - } } if ($update_res) { + close (RFLASH_LOG_FILE_HANDLE); $wait_node_num--; return; - } + } } if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_CHECK_ID_RESPONSE") { @@ -3472,28 +3510,42 @@ sub rflash_response { $status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} = $::SOFTWARE_URL . "/$update_id/attr/Priority"; - # Set next steps to activate the image - $next_status{ $node_info{$node}{cur_status} } = "RFLASH_UPDATE_ACTIVATE_REQUEST"; - $next_status{"RFLASH_UPDATE_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_ACTIVATE_RESPONSE"; - $next_status{"RFLASH_UPDATE_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; - $next_status{"RFLASH_UPDATE_CHECK_STATE_REQUEST"} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE"; - - $next_status{"RFLASH_SET_PRIORITY_REQUEST"} = "RFLASH_SET_PRIORITY_RESPONSE"; - $next_status{"RFLASH_SET_PRIORITY_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST"; my $upload_success_msg = "Firmware upload successful. Attempting to activate firmware: $::UPLOAD_FILE_VERSION (ID: $update_id)"; xCAT::SvrUtils::sendmsg("$upload_success_msg", $callback, $node); print RFLASH_LOG_FILE_HANDLE "$upload_success_msg\n"; - last; + } elsif ($update_version eq $::UPLOAD_PNOR_VERSION) { + $found_pnor_match = 1; + if ($::UPLOAD_PNOR_HASH_ID && ($::UPLOAD_PNOR_HASH_ID ne $update_id)) { + xCAT::SvrUtils::sendmsg([1,"Firmware uploaded but activation cancelled due to hash ID mismatch. $update_id does not match expected $::UPLOAD_PNOR_HASH_ID. Verify BMC firmware is at the latest level."], $callback, $node); + $wait_node_num--; + return; + } + $status_info{RFLASH_UPDATE_HOST_ACTIVATE_REQUEST}{init_url} = + $::SOFTWARE_URL . "/$update_id/attr/RequestedActivation"; + $status_info{RFLASH_UPDATE_CHECK_STATE_REQUEST}{init_url} = + $::SOFTWARE_URL . "/enumerate"; + $status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} = + $::SOFTWARE_URL . "/$update_id/attr/Priority"; + my $upload_success_msg = "Firmware upload successful. Attempting to activate firmware: $::UPLOAD_PNOR_VERSION (ID: $update_id)"; + xCAT::SvrUtils::sendmsg("$upload_success_msg", $callback, $node); + print RFLASH_LOG_FILE_HANDLE "$upload_success_msg\n"; } + } } if ($::UPLOAD_ACTIVATE_STREAM and (!$found_match or !$found_pnor_match) or !$found_match) { if (!exists($node_info{$node}{upload_wait_attemp})) { $node_info{$node}{upload_wait_attemp} = $::UPLOAD_WAIT_ATTEMPT; } + my $upload_file_version = ""; + if (!$found_match) { + $upload_file_version = $::UPLOAD_FILE_VERSION; + } else { + $upload_file_version = $::UPLOAD_PNOR_VERSION; + } if($node_info{$node}{upload_wait_attemp} > 0) { $node_info{$node}{upload_wait_attemp} --; - my $retry_msg = "Could not find ID for firmware $::UPLOAD_FILE_VERSION to activate, waiting $::UPLOAD_WAIT_INTERVAL seconds and retry..."; + my $retry_msg = "Could not find ID for firmware $upload_file_version to activate, waiting $::UPLOAD_WAIT_INTERVAL seconds and retry..."; if ($::VERBOSE) { xCAT::SvrUtils::sendmsg("$retry_msg", $callback, $node); } @@ -3502,13 +3554,13 @@ sub rflash_response { retry_after($node, "RFLASH_UPDATE_CHECK_ID_REQUEST", $::UPLOAD_WAIT_INTERVAL); return; } else { - my $no_firmware_msg = "Could not find firmware $::UPLOAD_FILE_VERSION after waiting $::UPLOAD_WAIT_TOTALTIME seconds."; + my $no_firmware_msg = "Could not find firmware $upload_file_version after waiting $::UPLOAD_WAIT_TOTALTIME seconds."; xCAT::SvrUtils::sendmsg([1,"$no_firmware_msg"], $callback, $node); print RFLASH_LOG_FILE_HANDLE "$no_firmware_msg\n"; close (RFLASH_LOG_FILE_HANDLE); $node_info{$node}{rst} = "$no_firmware_msg"; $wait_node_num--; - return; + return; } } } @@ -3540,7 +3592,13 @@ sub rflash_upload { # curl commands my $curl_login_cmd = "curl -c $cjar_id -k -H 'Content-Type: application/json' -X POST $request_url/login -d '" . $content_login . "'"; my $curl_logout_cmd = "curl -b $cjar_id -k -H 'Content-Type: application/json' -X POST $request_url/logout -d '" . $content_logout . "'"; - my $curl_upload_cmd = "curl -b $cjar_id -k -H 'Content-Type: application/octet-stream' -X PUT -T " . $::UPLOAD_FILE . " $request_url/upload/image/"; + + if (%fw_tar_files) { + foreach my $key (keys %fw_tar_files) { + my $curl_upload_cmd = "curl -b $cjar_id -k -H 'Content-Type: application/octet-stream' -X PUT -T " . $key . " $request_url/upload/image/"; + push(@curl_upload_cmds, $curl_upload_cmd); + } + } my $rflash_log_file = xCAT::Utils->full_path($node.".log", RFLASH_LOG_DIR); open (RFLASH_LOG_FILE_HANDLE, ">> $rflash_log_file"); @@ -3549,37 +3607,41 @@ sub rflash_upload { my $curl_login_result = `$curl_login_cmd -s`; my $h = from_json($curl_login_result); # convert command output to hash if ($h->{message} eq $::RESPONSE_OK) { - my $uploading_msg = "Uploading $::UPLOAD_FILE ..."; - # Login successfull, upload the file - if ($::VERBOSE) { - xCAT::SvrUtils::sendmsg("$uploading_msg", $callback, $node); - } - print RFLASH_LOG_FILE_HANDLE "$uploading_msg\n"; + foreach my $upload_cmd(@curl_upload_cmds){ + while((my $file,my $version)=each(%fw_tar_files)){ + my $uploading_msg = "Uploading $file ..."; + # Login successfull, upload the file + if ($::VERBOSE) { + xCAT::SvrUtils::sendmsg("$uploading_msg", $callback, $node); + } + print RFLASH_LOG_FILE_HANDLE "$uploading_msg\n"; - if ($xcatdebugmode) { - my $debugmsg = "RFLASH_FILE_UPLOAD_RESPONSE: CMD: $curl_upload_cmd"; - process_debug_info($node, $debugmsg); - } - my $curl_upload_result = `$curl_upload_cmd`; - $h = from_json($curl_upload_result); # convert command output to hash - if ($h->{message} eq $::RESPONSE_OK) { - # Upload successful, display message - my $upload_success_msg = "Firmware upload successful. Use -l option to list."; - unless ($::UPLOAD_AND_ACTIVATE) { - xCAT::SvrUtils::sendmsg("$upload_success_msg", $callback, $node); - } - print RFLASH_LOG_FILE_HANDLE "$upload_success_msg\n"; - # Try to logoff, no need to check result, as there is nothing else to do if failure - my $curl_logout_result = `$curl_logout_cmd -s`; - } - else { - my $upload_fail_msg = "Failed to upload update file $::UPLOAD_FILE :" . $h->{message} . " - " . $h->{data}->{description}; - xCAT::SvrUtils::sendmsg("$upload_fail_msg", $callback, $node); - print RFLASH_LOG_FILE_HANDLE "$upload_fail_msg\n"; - close (RFLASH_LOG_FILE_HANDLE); - $node_info{$node}{rst} = "$upload_fail_msg"; - return 1; + if ($xcatdebugmode) { + my $debugmsg = "RFLASH_FILE_UPLOAD_RESPONSE: CMD: $upload_cmd"; + process_debug_info($node, $debugmsg); + } + my $curl_upload_result = `$upload_cmd`; + $h = from_json($curl_upload_result); # convert command output to hash + if ($h->{message} eq $::RESPONSE_OK) { + # Upload successful, display message + my $upload_success_msg = "Firmware upload successful. Use -l option to list."; + unless ($::UPLOAD_AND_ACTIVATE or $::UPLOAD_ACTIVATE_STREAM) { + xCAT::SvrUtils::sendmsg("$upload_success_msg", $callback, $node); + } + print RFLASH_LOG_FILE_HANDLE "$upload_success_msg\n"; + # Try to logoff, no need to check result, as there is nothing else to do if failure + } else { + my $upload_fail_msg = "Failed to upload update file $file :" . $h->{message} . " - " . $h->{data}->{description}; + xCAT::SvrUtils::sendmsg("$upload_fail_msg", $callback, $node); + print RFLASH_LOG_FILE_HANDLE "$upload_fail_msg\n"; + close (RFLASH_LOG_FILE_HANDLE); + $node_info{$node}{rst} = "$upload_fail_msg"; + return 1; + } + } } + # Try to logoff, no need to check result, as there is nothing else to do if failure + my $curl_logout_result = `$curl_logout_cmd -s`; } else { my $unable_login_msg = "Unable to login :" . $h->{message} . " - " . $h->{data}->{description};