mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-22 11:42:05 +00:00
Merge pull request #4382 from xuweibj/T4331
rspconfig dump to allow admins capture logs
This commit is contained in:
commit
db20025558
@ -62,8 +62,12 @@ $::UPLOAD_WAIT_ATTEMPT = 6;
|
||||
$::UPLOAD_WAIT_INTERVAL = 10;
|
||||
$::UPLOAD_WAIT_TOTALTIME = int($::UPLOAD_WAIT_ATTEMPT*$::UPLOAD_WAIT_INTERVAL);
|
||||
|
||||
$::RPOWER_CHECK_INTERVAL = 2;
|
||||
$::RPOWER_MAX_RETRY = 30;
|
||||
$::RPOWER_CHECK_INTERVAL = 2;
|
||||
$::RPOWER_MAX_RETRY = 30;
|
||||
|
||||
$::RSPCONFIG_DUMP_INTERVAL = 30;
|
||||
$::RSPCONFIG_DUMP_MAX_RETRY = 20;
|
||||
$::RSPCONFIG_DUMP_WAIT_TOTALTIME = int($::RSPCONFIG_DUMP_INTERVAL*$::RSPCONFIG_DUMP_MAX_RETRY);
|
||||
|
||||
sub unsupported {
|
||||
my $callback = shift;
|
||||
@ -381,39 +385,42 @@ my %status_info = (
|
||||
RSPCONFIG_SSHCFG_RESPONSE => {
|
||||
process => \&rspconfig_sshcfg_response,
|
||||
},
|
||||
RSPCONFIG_DUMPLIST_REQUEST => {
|
||||
RSPCONFIG_DUMP_LIST_REQUEST => {
|
||||
method => "GET",
|
||||
init_url => "$openbmc_project_url/dump/enumerate",
|
||||
},
|
||||
RSPCONFIG_DUMPLIST_RESPONSE => {
|
||||
RSPCONFIG_DUMP_LIST_RESPONSE => {
|
||||
process => \&rspconfig_dump_response,
|
||||
},
|
||||
RSPCONFIG_DUMPCRT_REQUEST => {
|
||||
RSPCONFIG_DUMP_CHECK_RESPONSE => {
|
||||
process => \&rspconfig_dump_response,
|
||||
},
|
||||
RSPCONFIG_DUMP_CREATE_REQUEST => {
|
||||
method => "POST",
|
||||
init_url => "$openbmc_project_url/dump/action/CreateDump",
|
||||
data => "[]",
|
||||
},
|
||||
RSPCONFIG_DUMPCRT_RESPONSE => {
|
||||
RSPCONFIG_DUMP_CREATE_RESPONSE => {
|
||||
process => \&rspconfig_dump_response,
|
||||
},
|
||||
RSPCONFIG_DUMPCLR_REQUEST => {
|
||||
RSPCONFIG_DUMP_CLEAR_REQUEST => {
|
||||
method => "POST",
|
||||
init_url => "$openbmc_project_url/dump/entry/#ID#/action/Delete",
|
||||
data => "[]",
|
||||
},
|
||||
RSPCONFIG_DUMPCLRA_REQUEST => {
|
||||
RSPCONFIG_DUMP_CLEAR_ALL_REQUEST => {
|
||||
method => "POST",
|
||||
init_url => "$openbmc_project_url/dump/action/DeleteAll",
|
||||
data => "[]",
|
||||
},
|
||||
RSPCONFIG_DUMPCLR_RESPONSE => {
|
||||
RSPCONFIG_DUMP_CLEAR_RESPONSE => {
|
||||
process => \&rspconfig_dump_response,
|
||||
},
|
||||
RSPCONFIG_DUMPDWLD_REQUEST => {
|
||||
RSPCONFIG_DUMP_DOWNLOAD_REQUEST => {
|
||||
init_url => "download/dump/#ID#",
|
||||
process => \&rspconfig_dump_response,
|
||||
},
|
||||
RSPCONFIG_DUMPDWLD_RESPONSE => {
|
||||
RSPCONFIG_DUMP_DOWNLOAD_RESPONSE => {
|
||||
process => \&rspconfig_dump_response,
|
||||
},
|
||||
RVITALS_REQUEST => {
|
||||
@ -880,14 +887,15 @@ sub parse_args {
|
||||
return ([ 1, "Configure sshcfg must be issued without other options." ]) if ($num_subcommand > 1);
|
||||
$setorget = ""; # SSH Keys are copied using a RShellAPI, not REST API
|
||||
} elsif ($subcommand eq "dump") {
|
||||
my $option = $ARGV[1];
|
||||
my $option = "";
|
||||
$option = $ARGV[1] if (defined $ARGV[1]);
|
||||
if ($option =~ /^-d$|^--download$/) {
|
||||
return ([ 1, "No dump file ID specified" ]) unless ($ARGV[2]);
|
||||
return ([ 1, "Invalid parameter for $command $option $ARGV[2]" ]) if ($ARGV[2] !~ /^\d*$/);
|
||||
} elsif ($option =~ /^-c$|^--clear$/) {
|
||||
return ([ 1, "No dump file ID specified" ]) unless ($ARGV[2]);
|
||||
return ([ 1, "Invalid parameter for $command $option $ARGV[2]" ]) if ($ARGV[2] !~ /^\d*$/ and $ARGV[2] ne "all");
|
||||
} elsif ($option !~ /^-l$|^--list$|^-g$|^--generate$/) {
|
||||
} elsif ($option and $option !~ /^-l$|^--list$|^-g$|^--generate$/) {
|
||||
return ([ 1, "Invalid parameter for $command $option" ]);
|
||||
}
|
||||
return;
|
||||
@ -975,7 +983,7 @@ sub parse_args {
|
||||
my $action = "activate";
|
||||
if ($option_flag =~ /^-d$|^--delete$/) {
|
||||
$action = "delete";
|
||||
}
|
||||
}
|
||||
xCAT::SvrUtils::sendmsg("Attempting to $action ID=$flash_arguments[0], please wait...", $callback);
|
||||
}
|
||||
else {
|
||||
@ -1196,28 +1204,39 @@ sub parse_command_status {
|
||||
|
||||
$subcommand = $$subcommands[0];
|
||||
if ($subcommand eq "dump") {
|
||||
my $dump_opt = $$subcommands[1];
|
||||
my $dump_opt = "";
|
||||
$dump_opt = $$subcommands[1] if (defined $$subcommands[1]);
|
||||
if ($dump_opt =~ /-l|--list/) {
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMPLIST_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMPLIST_REQUEST} = "RSPCONFIG_DUMPLIST_RESPONSE";
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_LIST_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_LIST_REQUEST} = "RSPCONFIG_DUMP_LIST_RESPONSE";
|
||||
} elsif ($dump_opt =~ /-g|--generate/) {
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMPCRT_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMPCRT_REQUEST} = "RSPCONFIG_DUMPCRT_RESPONSE";
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CREATE_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_CREATE_REQUEST} = "RSPCONFIG_DUMP_CREATE_RESPONSE";
|
||||
} elsif ($dump_opt =~ /-c|--clear/) {
|
||||
if ($$subcommands[2] eq "all") {
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMPCLRA_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMPCLRA_REQUEST} = "RSPCONFIG_DUMPCLR_RESPONSE";
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CLEAR_ALL_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_CLEAR_ALL_REQUEST} = "RSPCONFIG_DUMP_CLEAR_RESPONSE";
|
||||
} else {
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMPCLR_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMPCLR_REQUEST} = "RSPCONFIG_DUMPCLR_RESPONSE";
|
||||
$status_info{RSPCONFIG_DUMPCLR_REQUEST}{init_url} =~ s/#ID#/$$subcommands[2]/g;
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CLEAR_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_CLEAR_REQUEST} = "RSPCONFIG_DUMP_CLEAR_RESPONSE";
|
||||
$status_info{RSPCONFIG_DUMP_CLEAR_REQUEST}{init_url} =~ s/#ID#/$$subcommands[2]/g;
|
||||
}
|
||||
$status_info{RSPCONFIG_DUMPCLR_RESPONSE}{argv} = $$subcommands[2];
|
||||
$status_info{RSPCONFIG_DUMP_CLEAR_RESPONSE}{argv} = $$subcommands[2];
|
||||
} elsif ($dump_opt =~ /-d|--download/) {
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMPDWLD_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMPDWLD_REQUEST} = "RSPCONFIG_DUMPDWLD_RESPONSE";
|
||||
$status_info{RSPCONFIG_DUMPDWLD_REQUEST}{init_url} =~ s/#ID#/$$subcommands[2]/g;
|
||||
$status_info{RSPCONFIG_DUMPDWLD_REQUEST}{argv} = $$subcommands[2];
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_DOWNLOAD_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_DOWNLOAD_REQUEST} = "RSPCONFIG_DUMP_DOWNLOAD_RESPONSE";
|
||||
$status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{init_url} =~ s/#ID#/$$subcommands[2]/g;
|
||||
$status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{argv} = $$subcommands[2];
|
||||
} else {
|
||||
# this section handles the dump support where no options are given and xCAT will
|
||||
# # handle the creation, waiting, and download of the dump across a given noderange
|
||||
xCAT::SvrUtils::sendmsg("Capturing BMC Diagnostic information, this will take some time...", $callback);
|
||||
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CREATE_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_CREATE_REQUEST} = "RSPCONFIG_DUMP_CREATE_RESPONSE";
|
||||
$next_status{RSPCONFIG_DUMP_CREATE_RESPONSE} = "RSPCONFIG_DUMP_LIST_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_LIST_REQUEST} = "RSPCONFIG_DUMP_CHECK_RESPONSE";
|
||||
$next_status{RSPCONFIG_DUMP_CHECK_RESPONSE} = "RSPCONFIG_DUMP_DOWNLOAD_REQUEST";
|
||||
$next_status{RSPCONFIG_DUMP_DOWNLOAD_REQUEST} = "RSPCONFIG_DUMP_DOWNLOAD_RESPONSE";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2663,30 +2682,55 @@ sub rspconfig_dump_response {
|
||||
|
||||
my $response_info = decode_json $response->content if (defined($response));
|
||||
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMPLIST_RESPONSE") {
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_LIST_RESPONSE" or $node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CHECK_RESPONSE") {
|
||||
my %dump_info = ();
|
||||
my $gen_check = 0;
|
||||
foreach my $key_url (keys %{$response_info->{data}}) {
|
||||
my %content = %{ ${ $response_info->{data} }{$key_url} };
|
||||
my $id;
|
||||
my $elased;
|
||||
if (defined $content{Elapsed}) {
|
||||
$id = $key_url;
|
||||
$id =~ s/.*\///g;
|
||||
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CHECK_RESPONSE") {
|
||||
if ($id eq $node_info{$node}{dump_id}) {
|
||||
# Save date when this dump was generated to use in downloaded filename
|
||||
$node_info{$node}{generated} = $content{Elapsed};
|
||||
$gen_check = 1;
|
||||
last;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($content{Elapsed});
|
||||
$mon += 1;
|
||||
$year += 1900;
|
||||
my $UTC_time = sprintf ("%02d/%02d/%04d %02d:%02d:%02d", $mon, $mday, $year, $hour, $min, $sec);
|
||||
$dump_info{$id} = "[$id] Elapsed: $UTC_time, Size: $content{Size}";
|
||||
$dump_info{$id} = "[$id] Generated: $UTC_time, Size: $content{Size}";
|
||||
}
|
||||
}
|
||||
|
||||
xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node) if (!%dump_info);
|
||||
xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node) if (!%dump_info and $node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_LIST_RESPONSE");
|
||||
foreach my $key ( sort { $a <=> $b } keys %dump_info) {
|
||||
xCAT::MsgUtils->message("I", { data => ["$node: $dump_info{$key}"] }, $callback) if ($dump_info{$key});
|
||||
}
|
||||
|
||||
if (!$gen_check and $node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CHECK_RESPONSE") {
|
||||
if (!exists($node_info{$node}{dump_wait_attemp})) {
|
||||
$node_info{$node}{dump_wait_attemp} = $::RSPCONFIG_DUMP_MAX_RETRY;
|
||||
}
|
||||
if ( $node_info{$node}{dump_wait_attemp} > 0) {
|
||||
$node_info{$node}{dump_wait_attemp} --;
|
||||
retry_after($node, "RSPCONFIG_DUMP_LIST_REQUEST", $::RSPCONFIG_DUMP_INTERVAL);
|
||||
return;
|
||||
} else {
|
||||
xCAT::SvrUtils::sendmsg([1,"Could not find dump $node_info{$node}{dump_id} after waiting $::RSPCONFIG_DUMP_WAIT_TOTALTIME seconds."], $callback, $node);
|
||||
$next_status{ $node_info{$node}{cur_status} } = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMPDWLD_REQUEST") {
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_DOWNLOAD_REQUEST") {
|
||||
my $child = xCAT::Utils->xfork;
|
||||
if (!defined($child)) {
|
||||
xCAT::SvrUtils::sendmsg("Failed to fork child process for rspconfig dump download.", $callback, $node);
|
||||
@ -2699,16 +2743,26 @@ sub rspconfig_dump_response {
|
||||
}
|
||||
}
|
||||
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMPCRT_RESPONSE") {
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CREATE_RESPONSE") {
|
||||
if ($response_info->{'message'} eq $::RESPONSE_OK) {
|
||||
my $dump_id = $response_info->{'data'};
|
||||
xCAT::SvrUtils::sendmsg("[$dump_id] success", $callback, $node);
|
||||
if ($response_info->{'data'}) {
|
||||
my $dump_id = $response_info->{'data'};
|
||||
if ($next_status{ $node_info{$node}{cur_status} }) {
|
||||
$node_info{$node}{dump_id} = $dump_id;
|
||||
xCAT::SvrUtils::sendmsg("Dump requested. Target ID is $dump_id, waiting for BMC to generate...", $callback, $node);
|
||||
} else {
|
||||
xCAT::SvrUtils::sendmsg("[$dump_id] success", $callback, $node);
|
||||
}
|
||||
} else {
|
||||
xCAT::SvrUtils::sendmsg([1, "BMC returned $::RESPONSE_OK but no ID was returned. Verify manually on the BMC."], $callback, $node);
|
||||
$next_status{ $node_info{$node}{cur_status} } = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMPCLR_RESPONSE") {
|
||||
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CLEAR_RESPONSE") {
|
||||
if ($response_info->{'message'} eq $::RESPONSE_OK) {
|
||||
my $dump_id = $status_info{RSPCONFIG_DUMPCLR_RESPONSE}{argv};
|
||||
my $dump_id = $status_info{RSPCONFIG_DUMP_CLEAR_RESPONSE}{argv};
|
||||
xCAT::SvrUtils::sendmsg("[$dump_id] clear", $callback, $node);
|
||||
}
|
||||
}
|
||||
@ -2717,6 +2771,8 @@ sub rspconfig_dump_response {
|
||||
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
|
||||
if ($node_info{$node}{method} || $status_info{ $node_info{$node}{cur_status} }{method}) {
|
||||
gen_send_request($node);
|
||||
} elsif ($status_info{ $node_info{$node}{cur_status} }->{process}) {
|
||||
$status_info{ $node_info{$node}{cur_status} }->{process}->($node, undef);
|
||||
}
|
||||
} else {
|
||||
$wait_node_num--;
|
||||
@ -2741,11 +2797,21 @@ sub dump_download_process {
|
||||
my $content_login = '{ "data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }';
|
||||
my $content_logout = '{ "data": [ ] }';
|
||||
my $cjar_id = "/tmp/_xcat_cjar.$node";
|
||||
my $file_name = "/var/log/xcat/dump/$node" . "_dump_$status_info{RSPCONFIG_DUMPDWLD_REQUEST}{argv}.tar.xz";
|
||||
my $dump_id;
|
||||
$dump_id = $status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{argv} if ($status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{argv});
|
||||
$dump_id = $node_info{$node}{dump_id} if ($node_info{$node}{dump_id});
|
||||
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($node_info{$node}{generated});
|
||||
$mon += 1;
|
||||
$year += 1900;
|
||||
my $file_name = "/var/log/xcat/dump/" . $year . $mon . $mday . $hour . $min . "_$node" . "_dump_$dump_id.tar.xz";
|
||||
my $down_url;
|
||||
$down_url = $status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{init_url};
|
||||
$down_url =~ s/#ID#/$dump_id/g;
|
||||
|
||||
xCAT::SvrUtils::sendmsg("Dump $dump_id generated. Downloading to $file_name", $callback, $node);
|
||||
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_dwld_cmd = "curl -J -b $cjar_id -k -H 'Content-Type: application/octet-stream' -X GET $request_url/$status_info{RSPCONFIG_DUMPDWLD_REQUEST}{init_url} -o $file_name";
|
||||
my $curl_dwld_cmd = "curl -J -b $cjar_id -k -H 'Content-Type: application/octet-stream' -X GET $request_url/$down_url -o $file_name";
|
||||
|
||||
my $curl_login_result = `$curl_login_cmd -s`;
|
||||
my $h = from_json($curl_login_result);
|
||||
@ -2754,13 +2820,13 @@ sub dump_download_process {
|
||||
my $curl_dwld_result = `$curl_dwld_cmd -s`;
|
||||
if (!$curl_dwld_result) {
|
||||
if ($xcatdebugmode) {
|
||||
my $debugmsg = "RSPCONFIG_DUMPDWLD_REQUEST: CMD: $curl_dwld_cmd";
|
||||
my $debugmsg = "RSPCONFIG_DUMP_DOWNLOAD_REQUEST: CMD: $curl_dwld_cmd";
|
||||
process_debug_info($node, $debugmsg);
|
||||
}
|
||||
xCAT::SvrUtils::sendmsg("Saved dump $status_info{RSPCONFIG_DUMPDWLD_REQUEST}{argv} as $file_name", $callback, $node);
|
||||
xCAT::SvrUtils::sendmsg("Downloaded Dump $dump_id to $file_name", $callback, $node) if ($::VERBOSE);
|
||||
`$curl_logout_cmd -s`;
|
||||
} else {
|
||||
xCAT::SvrUtils::sendmsg("Failed to download dump $status_info{RSPCONFIG_DUMPDWLD_REQUEST}{argv} :" . $h->{message} . " - " . $h->{data}->{description}, $callback, $node);
|
||||
xCAT::SvrUtils::sendmsg("Failed to download dump $dump_id :" . $h->{message} . " - " . $h->{data}->{description}, $callback, $node);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user