From 72a0a2b5a9b928d58a5269f203e5cf5562ba0bb7 Mon Sep 17 00:00:00 2001 From: XuWei Date: Wed, 1 Mar 2017 08:23:31 -0500 Subject: [PATCH 1/7] [DO NOT MERGER] framwork for openbmc support --- perl-xCAT/xCAT/Schema.pm | 35 +- xCAT-server/lib/perl/xCAT/OPENBMC.pm | 46 ++ xCAT-server/lib/xcat/plugins/openbmc.pm | 599 ++++++++++++++++++++++++ 3 files changed, 679 insertions(+), 1 deletion(-) create mode 100644 xCAT-server/lib/perl/xCAT/OPENBMC.pm create mode 100644 xCAT-server/lib/xcat/plugins/openbmc.pm diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 8a0639ea4..f99e74ac3 100755 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -443,6 +443,19 @@ passed as argument rather than by table value', disable => "Set to 'yes' or '1' to comment out this row.", }, }, + openbmc => { + cols => [qw(node bmc username password comments disable)], + keys => [qw(node)], + table_desc => 'Setting for nodes that are controlled by an on-board OpenBmc.', + descriptions => { + node => 'The node name or group name.', + bmc => 'The hostname of the BMC adapter.', + username => 'The BMC userid.', + password => 'The BMC password.', + comments => 'Any user-written notes.', + disable => "Set to 'yes' or '1' to comment out this row.", + }, + }, iscsi => { cols => [qw(node server target lun iname file userid passwd kernel kcmdline initrd comments disable)], keys => [qw(node)], @@ -586,7 +599,7 @@ passed as argument rather than by table value', descriptions => { node => 'The node name or group name.', power => 'The method to use to control the power of the node. If not set, the mgt attribute will be used. Valid values: ipmi, blade, hmc, ivm, fsp, kvm, esx, rhevm. If "ipmi", xCAT will search for this node in the ipmi table for more info. If "blade", xCAT will search for this node in the mp table. If "hmc", "ivm", or "fsp", xCAT will search for this node in the ppc table.', - mgt => 'The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details.', + mgt => 'The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details.', cons => 'The console method. If nodehm.serialport is set, this will default to the nodehm.mgt setting, otherwise it defaults to unused. Valid values: cyclades, mrv, or the values valid for the mgt attribute.', termserver => 'The hostname of the terminal server.', termport => 'The port number on the terminal server that this node is connected to.', @@ -2447,6 +2460,26 @@ my @nodeattrs = ( tabentry => 'mpa.urlpath', access_tabentry => 'mpa.mpa=attr:node', }, + +######################### + # openbmc table # +########################## + { attr_name => 'bmc', + only_if => 'mgt=openbmc', + tabentry => 'openbmc.bmc', + access_tabentry => 'openbmc.node=attr:node', + }, + { attr_name => 'bmcusername', + only_if => 'mgt=openbmc', + tabentry => 'openbmc.username', + access_tabentry => 'openbmc.node=attr:node', + }, + { attr_name => 'bmcpassword', + only_if => 'mgt=openbmc', + tabentry => 'openbmc.password', + access_tabentry => 'openbmc.node=attr:node', + }, + ###################### # nodepos table # ###################### diff --git a/xCAT-server/lib/perl/xCAT/OPENBMC.pm b/xCAT-server/lib/perl/xCAT/OPENBMC.pm new file mode 100644 index 000000000..424f83c36 --- /dev/null +++ b/xCAT-server/lib/perl/xCAT/OPENBMC.pm @@ -0,0 +1,46 @@ +#!/usr/bin/perl +## IBM(c) 2107 EPL license http://www.eclipse.org/legal/epl-v10.html + +package xCAT::OPENBMC; + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; +use strict; +use warnings "all"; + +use HTTP::Async; +use HTTP::Request; +use HTTP::Headers; +use HTTP::Cookies; +use Data::Dumper; + +my $header = HTTP::Headers->new('Content-Type' => 'application/json'); + +sub new { + my $async = shift; + $async = shift if (($async) && ($async =~ /OPENBMC/)); + my $url = shift; + my $content = shift; + my $method = 'POST'; + + my $id = send_request( $async, $method, $url, $content ); + + return $id; +} + +sub send_request { + my $async = shift; + $async = shift if (($async) && ($async =~ /OPENBMC/)); + my $method = shift; + my $url = shift; + my $content = shift; + + my $request = HTTP::Request->new( $method, $url, $header, $content ); + my $id = $async->add_with_opts($request, {}); + return $id; +} + +1; diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm new file mode 100644 index 000000000..31bec809a --- /dev/null +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -0,0 +1,599 @@ +#!/usr/bin/perl +## IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +package xCAT_plugin::openbmc; + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; +use strict; +use warnings "all"; + +use HTTP::Async; +use HTTP::Cookies; +use xCAT::OPENBMC; +use xCAT::Utils; +use xCAT::Table; +use xCAT::Usage; +use xCAT::SvrUtils; +use File::Basename; +use Data::Dumper; +use JSON; + +#------------------------------------------------------- + +=head3 handled_commands + + Return list of commands handled by this plugin + +=cut + +#------------------------------------------------------- +sub handled_commands { + return { + rpower => 'nodehm:mgt', + rinv => 'nodehm:mgt', + }; +} + +#------------------------------------------------------- + +# The hash table to store method and url for request, +# process function for response + +#------------------------------------------------------- +my %status_info = ( + LOGIN_REQUEST => { + method => "POST", + init_url => "/login", + }, + LOGIN_RESPONSE => { + process => \&login_response, + }, + + RPOWER_ON_REQUEST => { + method => "POST", + init_url => "/power/on", + }, + RPOWER_ON_RESPONSE => { + process => \&rpower_response, + }, + RPOWER_OFF_REQUEST => { + method => "POST", + init_url => "/power/off", + }, + RPOWER_OFF_RESPONSE => { + process => \&rpower_response, + }, + RPOWER_RESET_REQUEST => { + method => "POST", + init_url => "/power/reset", + }, + RPOWER_RESET_RESPONSE => { + process => \&rpower_response, + }, + RPOWER_STATUS_REQUEST => { + method => "GET", + init_url => "/org/openbmc/settings/host0", + }, + RPOWER_STATUS_RESPONSE => { + process => \&rpower_response, + }, + + RINV_MTHBRD_REQUEST => { + method => "GET", + init_url => "/org/openbmc/inventory/system/chassis/motherboard", + }, + RINV_MTHBRD_RESPONSE => { + process => \&rinv_response, + }, + RINV_CPU_REQUEST => { + method => "GET", + init_url => "/org/openbmc/inventory/system/chassis/motherboard/", + }, + RINV_CPU_RESPONSE => { + process => \&rinv_response, + }, + RINV_DIMM_REQUEST => { + method => "GET", + init_url => "/org/openbmc/inventory/system/chassis/motherboard/", + }, + RINV_DIMM_RESPONSE => { + process => \&rinv_response, + }, +); + + +#----------------------------- + +=head3 %node_info + + $node_info = ( + $node => { + bmc => "x.x.x.x", + username => "username", + password => "password", + cur_status => "LOGIN_REQUEST", + cur_url => "", + method => "", + back_urls => (), + $src => "", + }, + ); + + 'cur_url', 'method', 'back_urls' used for path has a trailing-slash + +=cut + +#----------------------------- +my %node_info = (); + +my %next_status = (); + +my %handle_id_node = (); + +my $wait_node_num; + +my $async; + +my $cookie_jar; + +my $callback; + +#------------------------------------------------------- + +=head3 preprocess_request + + preprocess the command + +=cut + +#------------------------------------------------------- +sub preprocess_request { + my $request = shift; + if (defined $request->{_xcatpreprocessed}->[0] and $request->{_xcatpreprocessed}->[0] == 1) { + return [$request]; + } + + $callback = shift; + + my $command = $request->{command}->[0]; + my $noderange = $request->{node}; + my $extrargs = $request->{arg}; + my @exargs = ($request->{arg}); + my @requests; + + if (ref($extrargs)) { + @exargs = @$extrargs; + } + my $usage_string = xCAT::Usage->parseCommand($command, @exargs); + if ($usage_string) { + $callback->({ data => [$usage_string] }); + $request = {}; + return; + } + + my $parse_result = parse_args($command, $extrargs); + if (ref($parse_result) eq 'ARRAY') { + $callback->({ error => $parse_result->[1], errorcode => $parse_result->[0] }); + $request = {}; + return; + } + + my $sn = xCAT::ServiceNodeUtils->get_ServiceNode($noderange, "xcat", "MN"); + foreach my $snkey (keys %$sn) { + my $reqcopy = {%$request}; + $reqcopy->{node} = $sn->{$snkey}; + $reqcopy->{'_xcatdest'} = $snkey; + $reqcopy->{_xcatpreprocessed}->[0] = 1; + push @requests, $reqcopy; + } + + return \@requests; +} + +#------------------------------------------------------- + +=head3 process_request + + Process the command + +=cut + +#------------------------------------------------------- +sub process_request { + my $request = shift; + my $noderange = $request->{node}; + + parse_node_info($noderange); + + $cookie_jar = HTTP::Cookies->new({}); + $async = HTTP::Async->new( + cookie_jar => $cookie_jar, + ssl_options => { + SSL_verify_mode => 0, + }, + ); + + my $bmcip; + my $login_url; + my $handle_id; + my $content; + $wait_node_num = keys %node_info; + + foreach my $node (keys %node_info) { + $bmcip = $node_info{$node}{bmc}; + $login_url = "https://$bmcip/login"; + $content = '{"data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }'; + $handle_id = xCAT::OPENBMC->new($async, $login_url, $content); + $handle_id_node{$handle_id} = $node; + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; + } + + while (1) { + last unless ($wait_node_num); + while (my ($response, $handle_id) = $async->wait_for_next_response) { + deal_with_response($handle_id, $response); + } + } + + return; +} + +#------------------------------------------------------- + +=head3 parse_args + + Parse the command line options and operands + +=cut + +#------------------------------------------------------- +sub parse_args { + my $command = shift; + my $extrargs = shift; + + $next_status{LOGIN_REQUEST} = "LOGIN_RESPONSE"; + + if ($command eq "rpower") { + if (!defined($extrargs)) { + return ([ 1, "No option specified for rpower" ]); + } + + if (scalar(@ARGV) > 1) { + return ([ 1, "Only one option is supportted at the same time" ]); + } + + my $subcommand = $ARGV[0]; + +# now, only support status, delete when other command supported +if ($subcommand ne "status" and $subcommand ne "state" and $subcommand ne "stat") { + return ([ 1, "Only support status check currently" ]) +} +#---------------------------------------------------------------- + + if ($subcommand eq "on") { + $next_status{LOGIN_RESPONSE} = "RPOWER_ON_REQUEST"; + $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; + } elsif ($subcommand eq "off") { + $next_status{LOGIN_RESPONSE} = "RPOWER_OFF_REQUEST"; + $next_status{RPOWER_OFF_REQUEST} = "RPOWER_OFF_RESPONSE"; + } elsif ($subcommand eq "status" or $subcommand eq "state" or $subcommand eq "stat") { + $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; + $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; + } elsif ($subcommand eq "boot") { + $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; + $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; + $next_status{RPOWER_STATUS_RESPONSE}{OFF} = "RPOWER_ON_REQUEST"; + $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; + $next_status{RPOWER_STATUS_RESPONSE}{ON} = "RPOWER_RESET_REQUEST"; + $next_status{RPOWER_RESET_REQUEST} = "RPOWER_RESET_RESPONSE"; + } else { + return ([ 1, "$subcommand is not supported for rpower" ]); + } + } + + if ($command eq "rinv") { + if (!defined($extrargs)) { + return ([ 1, "No option specified for rpower" ]); + } + + if (scalar(@ARGV) > 1) { + return ([ 1, "Only one option is supportted at the same time" ]); + } + + my $subcommand = $ARGV[0]; + + if ($subcommand eq "cpu") { + $next_status{LOGIN_RESPONSE} = "RINV_CPU_REQUEST"; + $next_status{RINV_CPU_REQUEST} = "RINV_CPU_RESPONSE"; + } elsif ($subcommand eq "dimm") { + $next_status{LOGIN_RESPONSE} = "RINV_DIMM_REQUEST"; + $next_status{RINV_DIMM_REQUEST} = "RINV_DIMM_RESPONSE"; + } elsif ($subcommand eq "all") { + $next_status{LOGIN_RESPONSE} = "RINV_MTHBRD_REQUEST"; + $next_status{RINV_MTHBRD_REQUEST} = "RINV_MTHBRD_RESPONSE"; + $next_status{RINV_MTHBRD_RESPONSE} = "RINV_CPU_REQUEST"; + $next_status{RINV_CPU_REQUEST} = "RINV_CPU_RESPONSE"; + $next_status{RINV_CPU_RESPONSE} = "RINV_DIMM_REQUEST"; + $next_status{RINV_DIMM_REQUEST} = "RINV_DIMM_RESPONSE"; + } else { + return ([ 1, "Only 'cpu','dimm','all' are supportted at the same time" ]); + } + } + + print Dumper(%next_status) . "\n"; + + return; +} + + +#------------------------------------------------------- + +=head3 parse_node_info + + Parse the node information: bmc, username, password + +=cut + +#------------------------------------------------------- +sub parse_node_info { + my $noderange = shift; + + my $table = xCAT::Table->new('openbmc'); + my $tablehash = $table->getNodesAttribs(\@$noderange, ['bmc', 'username', 'password']); + + foreach my $node (@$noderange) { + if (defined($tablehash->{$node}->[0])) { + if ($tablehash->{$node}->[0]->{'bmc'}) { + $node_info{$node}{bmc} = $tablehash->{$node}->[0]->{'bmc'}; + } else { + xCAT::SvrUtils::sendmsg("Unable to get attribute bmc", $callback, $node); + next; + } + + if ($tablehash->{$node}->[0]->{'username'}) { + $node_info{$node}{username} = $tablehash->{$node}->[0]->{'username'}; + } else { + xCAT::SvrUtils::sendmsg("Unable to get attribute username", $callback, $node); + delete $node_info{$node}; + next; + } + + if ($tablehash->{$node}->[0]->{'password'}) { + $node_info{$node}{password} = $tablehash->{$node}->[0]->{'password'}; + } else { + xCAT::SvrUtils::sendmsg("Unable to get attribute password", $callback, $node); + delete $node_info{$node}; + next; + } + + $node_info{$node}{cur_status} = "LOGIN_REQUEST"; + } else { + xCAT::SvrUtils::sendmsg("Unable to get information from openbmc table", $callback, $node); + next; + } + } + + print Dumper(%node_info) ."\n"; + + return; +} + +#------------------------------------------------------- + +=head3 gen_send_request + + Generate request's information + If the node has method itself, use it as request's method. + If not, use method %status_info defined. + If the node has cur_url, check whether also has sub_urls. + If has, request's url is join cur_url and one in sub_urls(use one at once to check which is needed). + If not, use method %status_info defined. + use xCAT::OPENBMC->send_request send request + store handle_id and mapping node + Input: + $node: nodename of current node + +=cut + +#------------------------------------------------------- +sub gen_send_request { + my $node = shift; + my $method; + my $request_url; + my $content; + + if ($node_info{$node}{method}) { + $method = $node_info{$node}{method}; + } else { + $method = $status_info{ $node_info{$node}{cur_status} }{method}; + } + + if ($node_info{$node}{cur_url}) { + $request_url = $node_info{$node}{cur_url}; + } else { + $request_url = $status_info{ $node_info{$node}{cur_status} }{init_url}; + } + $request_url = "https://" . $node_info{$node}{bmc} . $request_url; + + my $handle_id = xCAT::OPENBMC->send_request($async, $method, $request_url, $content); + $handle_id_node{$handle_id} = $node; + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; + + return; +} + +#------------------------------------------------------- + +=head3 deal_with_response + + Check response's status_line and + Input: + $handle_id: Async return ID with response + $response: Async return response + +=cut + +#------------------------------------------------------- +sub deal_with_response { + my $handle_id = shift; + my $response = shift; + my $node = $handle_id_node{$handle_id}; + + if ($response->status_line ne "200 OK") { + my $response_info = decode_json $response->content; + xCAT::SvrUtils::sendmsg($response_info->{'data'}->{'description'}, $callback, $node); + $wait_node_num--; + return; + } + + delete $handle_id_node{$handle_id}; + $status_info{ $node_info{$node}{cur_status} }->{process}->($node, $response); + + return; +} + +#------------------------------------------------------- + +=head3 login_response + + Deal with response of login + Input: + $node: nodename of current response + $response: Async return response + +=cut + +#------------------------------------------------------- +sub login_response { + my $node = shift; + my $response = shift; + + if ($next_status{ $node_info{$node}{cur_status} }) { + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; + gen_send_request($node); + } + + return; +} + +#------------------------------------------------------- + +=head3 rpower_response + + Deal with response of rpower command + Input: + $node: nodename of current response + $response: Async return response + +=cut + +#------------------------------------------------------- +sub rpower_response { + my $node = shift; + my $response = shift; + + my $response_info = decode_json $response->content; + + if ($node_info{$node}{cur_status} eq "RPOWER_ON_RESPONSE") { + xCAT::SvrUtils::sendmsg("on", $callback, $node); + } + + if ($node_info{$node}{cur_status} eq "RPOWER_OFF_RESPONSE") { + xCAT::SvrUtils::sendmsg("off", $callback, $node); + } + + if ($node_info{$node}{cur_status} eq "RPOWER_STATUS_RESPONSE") { + xCAT::SvrUtils::sendmsg($response_info->{'data'}->{system_state}, $callback, $node); + } + + if ($next_status{ $node_info{$node}{cur_status} }) { + if ($node_info{$node}{cur_status} eq "RPOWER_STATUS_RESPONSE") { + if ($response_info->{'data'}->{system_state} =~ /HOST_POWERED_ON/) { + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{ON}; + } else { + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{OFF}; + } + } else { + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; + } + gen_send_request($node); + + } else { + $wait_node_num--; + } + + return; +} + +sub rinv_response { + my $node = shift; + my $response = shift; + + my $response_info = decode_json $response->content; + + my %rinv_response = ( + RINV_CPU_RESPONSE => { + map_str => "cpu", + repeat => "RINV_CPU_REQUEST", + }, + RINV_DIMM_RESPONSE => { + map_str => "dimm", + repeat => "RINV_DIMM_REQUEST", + }, + + ); + + my $grep_string = $rinv_response{$node_info{$node}{cur_status}}{map_str}; + my $repeat_status = $rinv_response{$node_info{$node}{cur_status}}{repeat}; + + if ($node_info{$node}{cur_status} ne "RINV_MTHBRD_RESPONSE") { + if (ref($response_info->{data}) eq "ARRAY") { + foreach my $rsp_url (@{$response_info->{data}}) { + if ($rsp_url =~ /\/$grep_string/) { + push @{ $node_info{$node}{back_urls} }, $rsp_url; + } + } + + $node_info{$node}{cur_url} = shift @{ $node_info{$node}{back_urls} }; + $node_info{$node}{cur_status} = $repeat_status; + $node_info{$node}{src} = basename $node_info{$node}{cur_url}; + gen_send_request($node); + } elsif (ref($response_info->{data}) eq "HASH") { + my $cpu_info; + foreach my $key (keys %{$response_info->{data}}) { + $cpu_info = uc ($node_info{$node}{src}) . " " . $key . " : " . ${$response_info->{data}}{$key}; + xCAT::SvrUtils::sendmsg("$cpu_info", $callback, $node); + } + + if (@{ $node_info{$node}{back_urls} }) { + $node_info{$node}{cur_url} = shift @{ $node_info{$node}{back_urls} }; + $node_info{$node}{cur_status} = $repeat_status; + $node_info{$node}{src} = basename $node_info{$node}{cur_url}; + gen_send_request($node); + } else { + if ($next_status{ $node_info{$node}{cur_status} }) { + delete $node_info{$node}{cur_url}; + delete $node_info{$node}{src}; + gen_send_request($node); + } else { + $wait_node_num--; + } + } + } + } + + #print Dumper(%node_info) ."\n"; + return; +} + + +1; + + + + + From 7dc91e22f80bd78aad727ec74dfc83e5ecc7e117 Mon Sep 17 00:00:00 2001 From: XuWei Date: Mon, 6 Mar 2017 03:09:24 -0500 Subject: [PATCH 2/7] change rinv link and response --- xCAT-server/lib/xcat/plugins/openbmc.pm | 127 +++++++----------------- 1 file changed, 37 insertions(+), 90 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index 31bec809a..aa807a266 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -34,10 +34,11 @@ use JSON; sub handled_commands { return { rpower => 'nodehm:mgt', - rinv => 'nodehm:mgt', + rinv => 'nodehm:mgt', }; } +my $pre_url = "/org/openbmc"; #------------------------------------------------------- # The hash table to store method and url for request, @@ -76,31 +77,17 @@ my %status_info = ( }, RPOWER_STATUS_REQUEST => { method => "GET", - init_url => "/org/openbmc/settings/host0", + init_url => "$pre_url/settings/host0", }, RPOWER_STATUS_RESPONSE => { process => \&rpower_response, }, - RINV_MTHBRD_REQUEST => { + RINV_REQUEST => { method => "GET", - init_url => "/org/openbmc/inventory/system/chassis/motherboard", + init_url => "$pre_url/inventory/enumerate", }, - RINV_MTHBRD_RESPONSE => { - process => \&rinv_response, - }, - RINV_CPU_REQUEST => { - method => "GET", - init_url => "/org/openbmc/inventory/system/chassis/motherboard/", - }, - RINV_CPU_RESPONSE => { - process => \&rinv_response, - }, - RINV_DIMM_REQUEST => { - method => "GET", - init_url => "/org/openbmc/inventory/system/chassis/motherboard/", - }, - RINV_DIMM_RESPONSE => { + RINV_RESPONSE => { process => \&rinv_response, }, ); @@ -119,7 +106,6 @@ my %status_info = ( cur_url => "", method => "", back_urls => (), - $src => "", }, ); @@ -268,11 +254,11 @@ sub parse_args { my $subcommand = $ARGV[0]; -# now, only support status, delete when other command supported -if ($subcommand ne "status" and $subcommand ne "state" and $subcommand ne "stat") { - return ([ 1, "Only support status check currently" ]) -} -#---------------------------------------------------------------- + # now, only support status, delete when other command supported + if ($subcommand ne "status" and $subcommand ne "state" and $subcommand ne "stat") { + return ([ 1, "Only support status check currently" ]) + } + #---------------------------------------------------------------- if ($subcommand eq "on") { $next_status{LOGIN_RESPONSE} = "RPOWER_ON_REQUEST"; @@ -306,21 +292,12 @@ if ($subcommand ne "status" and $subcommand ne "state" and $subcommand ne "stat" my $subcommand = $ARGV[0]; - if ($subcommand eq "cpu") { - $next_status{LOGIN_RESPONSE} = "RINV_CPU_REQUEST"; - $next_status{RINV_CPU_REQUEST} = "RINV_CPU_RESPONSE"; - } elsif ($subcommand eq "dimm") { - $next_status{LOGIN_RESPONSE} = "RINV_DIMM_REQUEST"; - $next_status{RINV_DIMM_REQUEST} = "RINV_DIMM_RESPONSE"; - } elsif ($subcommand eq "all") { - $next_status{LOGIN_RESPONSE} = "RINV_MTHBRD_REQUEST"; - $next_status{RINV_MTHBRD_REQUEST} = "RINV_MTHBRD_RESPONSE"; - $next_status{RINV_MTHBRD_RESPONSE} = "RINV_CPU_REQUEST"; - $next_status{RINV_CPU_REQUEST} = "RINV_CPU_RESPONSE"; - $next_status{RINV_CPU_RESPONSE} = "RINV_DIMM_REQUEST"; - $next_status{RINV_DIMM_REQUEST} = "RINV_DIMM_RESPONSE"; + if ($subcommand eq "cpu" or $subcommand eq "dimm" or $subcommand eq "bios" or $subcommand eq "all") { + $next_status{LOGIN_RESPONSE} = "RINV_REQUEST"; + $next_status{RINV_REQUEST} = "RINV_RESPONSE"; + $status_info{RINV_RESPONSE}{argv} = "$subcommand"; } else { - return ([ 1, "Only 'cpu','dimm','all' are supportted at the same time" ]); + return ([ 1, "Only 'cpu','dimm', 'bios','all' are supportted at the same time" ]); } } @@ -535,65 +512,35 @@ sub rinv_response { my $response_info = decode_json $response->content; - my %rinv_response = ( - RINV_CPU_RESPONSE => { - map_str => "cpu", - repeat => "RINV_CPU_REQUEST", - }, - RINV_DIMM_RESPONSE => { - map_str => "dimm", - repeat => "RINV_DIMM_REQUEST", - }, - - ); + my $grep_string = $status_info{RINV_RESPONSE}{argv}; + my $src; + my $content_info; - my $grep_string = $rinv_response{$node_info{$node}{cur_status}}{map_str}; - my $repeat_status = $rinv_response{$node_info{$node}{cur_status}}{repeat}; - - if ($node_info{$node}{cur_status} ne "RINV_MTHBRD_RESPONSE") { - if (ref($response_info->{data}) eq "ARRAY") { - foreach my $rsp_url (@{$response_info->{data}}) { - if ($rsp_url =~ /\/$grep_string/) { - push @{ $node_info{$node}{back_urls} }, $rsp_url; - } - } - - $node_info{$node}{cur_url} = shift @{ $node_info{$node}{back_urls} }; - $node_info{$node}{cur_status} = $repeat_status; - $node_info{$node}{src} = basename $node_info{$node}{cur_url}; - gen_send_request($node); - } elsif (ref($response_info->{data}) eq "HASH") { - my $cpu_info; - foreach my $key (keys %{$response_info->{data}}) { - $cpu_info = uc ($node_info{$node}{src}) . " " . $key . " : " . ${$response_info->{data}}{$key}; - xCAT::SvrUtils::sendmsg("$cpu_info", $callback, $node); - } - - if (@{ $node_info{$node}{back_urls} }) { - $node_info{$node}{cur_url} = shift @{ $node_info{$node}{back_urls} }; - $node_info{$node}{cur_status} = $repeat_status; - $node_info{$node}{src} = basename $node_info{$node}{cur_url}; - gen_send_request($node); + foreach my $key_url (keys %{$response_info->{data}}) { + if ($grep_string eq "all" or $key_url =~ /\/$grep_string/) { + if ($key_url =~ /\/(cpu\d*)\/(\w+)/) { + $src = "$1 $2"; } else { - if ($next_status{ $node_info{$node}{cur_status} }) { - delete $node_info{$node}{cur_url}; - delete $node_info{$node}{src}; - gen_send_request($node); - } else { - $wait_node_num--; - } + $src = basename $key_url; + } + + my %content = %{ ${ $response_info->{data} }{$key_url} }; + foreach my $key (keys %content) { + $content_info = uc ($src) . " " . $key . " : " . $content{$key}; + xCAT::SvrUtils::sendmsg("$content_info", $callback, $node); } } + } + + if ($next_status{ $node_info{$node}{cur_status} }) { + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; + gen_send_request($node); + } else { + $wait_node_num--; } - #print Dumper(%node_info) ."\n"; return; } 1; - - - - - From 190b218cba9cd295957aca06ff34cc6db6a553c8 Mon Sep 17 00:00:00 2001 From: XuWei Date: Tue, 7 Mar 2017 00:57:56 -0500 Subject: [PATCH 3/7] add more print message --- xCAT-server/lib/xcat/plugins/openbmc.pm | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index aa807a266..e9c96ad21 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -105,7 +105,7 @@ my %status_info = ( cur_status => "LOGIN_REQUEST", cur_url => "", method => "", - back_urls => (), + back_urls => (), }, ); @@ -216,6 +216,7 @@ sub process_request { $handle_id = xCAT::OPENBMC->new($async, $login_url, $content); $handle_id_node{$handle_id} = $node; $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; + print "$node: POST $login_url -d $content\n"; } while (1) { @@ -399,6 +400,7 @@ sub gen_send_request { my $handle_id = xCAT::OPENBMC->send_request($async, $method, $request_url, $content); $handle_id_node{$handle_id} = $node; $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; + print "$node: $method $request_url\n"; return; } @@ -420,14 +422,23 @@ sub deal_with_response { my $response = shift; my $node = $handle_id_node{$handle_id}; + delete $handle_id_node{$handle_id}; + if ($response->status_line ne "200 OK") { my $response_info = decode_json $response->content; - xCAT::SvrUtils::sendmsg($response_info->{'data'}->{'description'}, $callback, $node); + my $error; + if ($response_info->{'data'}->{'description'} =~ /path or object not found: (.+)/) { + $error = "path or object not found $1"; + } else { + $error = $response_info->{'data'}->{'description'}; + } + xCAT::SvrUtils::sendmsg([1, $error], $callback, $node); $wait_node_num--; return; } - delete $handle_id_node{$handle_id}; + print "$node: " . lc ($node_info{$node}{cur_status}) . " " . $response->status_line . "\n"; + $status_info{ $node_info{$node}{cur_status} }->{process}->($node, $response); return; From d46bbb37e507fa73eeec9a89ef6a99ffb78d0c0c Mon Sep 17 00:00:00 2001 From: XuWei Date: Thu, 9 Mar 2017 03:18:56 -0500 Subject: [PATCH 4/7] add power on/off --- xCAT-server/lib/xcat/plugins/openbmc.pm | 52 ++++++++++++++----------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index e9c96ad21..45e1c28d2 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -56,14 +56,14 @@ my %status_info = ( RPOWER_ON_REQUEST => { method => "POST", - init_url => "/power/on", + init_url => "$pre_url/control/chassis0/action/powerOn", }, RPOWER_ON_RESPONSE => { process => \&rpower_response, }, RPOWER_OFF_REQUEST => { method => "POST", - init_url => "/power/off", + init_url => "$pre_url/control/chassis0/action/powerOff", }, RPOWER_OFF_RESPONSE => { process => \&rpower_response, @@ -77,6 +77,7 @@ my %status_info = ( }, RPOWER_STATUS_REQUEST => { method => "GET", + #init_url => "$pre_url/state/host0", init_url => "$pre_url/settings/host0", }, RPOWER_STATUS_RESPONSE => { @@ -216,7 +217,7 @@ sub process_request { $handle_id = xCAT::OPENBMC->new($async, $login_url, $content); $handle_id_node{$handle_id} = $node; $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; - print "$node: POST $login_url -d $content\n"; + print "$node: DEBUG POST $login_url -d $content\n"; } while (1) { @@ -255,12 +256,6 @@ sub parse_args { my $subcommand = $ARGV[0]; - # now, only support status, delete when other command supported - if ($subcommand ne "status" and $subcommand ne "state" and $subcommand ne "stat") { - return ([ 1, "Only support status check currently" ]) - } - #---------------------------------------------------------------- - if ($subcommand eq "on") { $next_status{LOGIN_RESPONSE} = "RPOWER_ON_REQUEST"; $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; @@ -270,13 +265,13 @@ sub parse_args { } elsif ($subcommand eq "status" or $subcommand eq "state" or $subcommand eq "stat") { $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; - } elsif ($subcommand eq "boot") { - $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; - $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; - $next_status{RPOWER_STATUS_RESPONSE}{OFF} = "RPOWER_ON_REQUEST"; - $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; - $next_status{RPOWER_STATUS_RESPONSE}{ON} = "RPOWER_RESET_REQUEST"; - $next_status{RPOWER_RESET_REQUEST} = "RPOWER_RESET_RESPONSE"; + # } elsif ($subcommand eq "boot") { + # $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; + # $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; + # $next_status{RPOWER_STATUS_RESPONSE}{OFF} = "RPOWER_ON_REQUEST"; + # $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; + # $next_status{RPOWER_STATUS_RESPONSE}{ON} = "RPOWER_RESET_REQUEST"; + # $next_status{RPOWER_RESET_REQUEST} = "RPOWER_RESET_RESPONSE"; } else { return ([ 1, "$subcommand is not supported for rpower" ]); } @@ -382,7 +377,7 @@ sub gen_send_request { my $node = shift; my $method; my $request_url; - my $content; + my $content = '{"data": [] }';; if ($node_info{$node}{method}) { $method = $node_info{$node}{method}; @@ -400,7 +395,14 @@ sub gen_send_request { my $handle_id = xCAT::OPENBMC->send_request($async, $method, $request_url, $content); $handle_id_node{$handle_id} = $node; $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; - print "$node: $method $request_url\n"; + + my $debug_info; + if ($method eq "GET") { + $debug_info = "$node: DEBUG $method $request_url"; + } else { + $debug_info = "$node: DEBUG $method $request_url -d $content"; + } + print "$debug_info\n"; return; } @@ -425,19 +427,23 @@ sub deal_with_response { delete $handle_id_node{$handle_id}; if ($response->status_line ne "200 OK") { - my $response_info = decode_json $response->content; my $error; - if ($response_info->{'data'}->{'description'} =~ /path or object not found: (.+)/) { - $error = "path or object not found $1"; + if ($response->status_line eq "503 Service Unavailable") { + $error = "Service Unavailable"; } else { - $error = $response_info->{'data'}->{'description'}; + my $response_info = decode_json $response->content; + if ($response_info->{'data'}->{'description'} =~ /path or object not found: (.+)/) { + $error = "path or object not found $1"; + } else { + $error = $response_info->{'data'}->{'description'}; + } } xCAT::SvrUtils::sendmsg([1, $error], $callback, $node); $wait_node_num--; return; } - print "$node: " . lc ($node_info{$node}{cur_status}) . " " . $response->status_line . "\n"; + print "$node: DEBUG " . lc ($node_info{$node}{cur_status}) . " " . $response->status_line . "\n"; $status_info{ $node_info{$node}{cur_status} }->{process}->($node, $response); From d07b55ff2d200bcc6d33e14b881058f49fdfc082 Mon Sep 17 00:00:00 2001 From: XuWei Date: Fri, 10 Mar 2017 03:02:12 -0500 Subject: [PATCH 5/7] update rpower url and add reset --- xCAT-server/lib/xcat/plugins/openbmc.pm | 82 +++++++++++++++++-------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index 45e1c28d2..a784d54e4 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -55,30 +55,32 @@ my %status_info = ( }, RPOWER_ON_REQUEST => { - method => "POST", - init_url => "$pre_url/control/chassis0/action/powerOn", + method => "PUT", + init_url => "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", + data => "xyz.openbmc_project.State.Host.Transition.On", }, RPOWER_ON_RESPONSE => { process => \&rpower_response, }, RPOWER_OFF_REQUEST => { - method => "POST", - init_url => "$pre_url/control/chassis0/action/powerOff", + method => "PUT", + init_url => "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", + data => "xyz.openbmc_project.State.Host.Transition.Off", }, RPOWER_OFF_RESPONSE => { process => \&rpower_response, }, RPOWER_RESET_REQUEST => { - method => "POST", - init_url => "/power/reset", + method => "PUT", + init_url => "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", + data => "xyz.openbmc_project.State.Host.Transition.Reboot", }, RPOWER_RESET_RESPONSE => { process => \&rpower_response, }, RPOWER_STATUS_REQUEST => { method => "GET", - #init_url => "$pre_url/state/host0", - init_url => "$pre_url/settings/host0", + init_url => "/xyz/openbmc_project/state/host0", }, RPOWER_STATUS_RESPONSE => { process => \&rpower_response, @@ -262,16 +264,19 @@ sub parse_args { } elsif ($subcommand eq "off") { $next_status{LOGIN_RESPONSE} = "RPOWER_OFF_REQUEST"; $next_status{RPOWER_OFF_REQUEST} = "RPOWER_OFF_RESPONSE"; + } elsif ($subcommand eq "reset") { + $next_status{LOGIN_RESPONSE} = "RPOWER_RESET_REQUEST"; + $next_status{RPOWER_RESET_REQUEST} = "RPOWER_RESET_RESPONSE"; } elsif ($subcommand eq "status" or $subcommand eq "state" or $subcommand eq "stat") { $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; - # } elsif ($subcommand eq "boot") { - # $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; - # $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; - # $next_status{RPOWER_STATUS_RESPONSE}{OFF} = "RPOWER_ON_REQUEST"; - # $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; - # $next_status{RPOWER_STATUS_RESPONSE}{ON} = "RPOWER_RESET_REQUEST"; - # $next_status{RPOWER_RESET_REQUEST} = "RPOWER_RESET_RESPONSE"; + } elsif ($subcommand eq "boot") { + $next_status{LOGIN_RESPONSE} = "RPOWER_STATUS_REQUEST"; + $next_status{RPOWER_STATUS_REQUEST} = "RPOWER_STATUS_RESPONSE"; + $next_status{RPOWER_STATUS_RESPONSE}{OFF} = "RPOWER_ON_REQUEST"; + $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE"; + $next_status{RPOWER_STATUS_RESPONSE}{ON} = "RPOWER_RESET_REQUEST"; + $next_status{RPOWER_RESET_REQUEST} = "RPOWER_RESET_RESPONSE"; } else { return ([ 1, "$subcommand is not supported for rpower" ]); } @@ -377,7 +382,7 @@ sub gen_send_request { my $node = shift; my $method; my $request_url; - my $content = '{"data": [] }';; + my $content; if ($node_info{$node}{method}) { $method = $node_info{$node}{method}; @@ -385,6 +390,10 @@ sub gen_send_request { $method = $status_info{ $node_info{$node}{cur_status} }{method}; } + if ($status_info{ $node_info{$node}{cur_status} }{data}) { + $content = '{"data":"' . $status_info{ $node_info{$node}{cur_status} }{data} . '"}'; + } + if ($node_info{$node}{cur_url}) { $request_url = $node_info{$node}{cur_url}; } else { @@ -432,7 +441,9 @@ sub deal_with_response { $error = "Service Unavailable"; } else { my $response_info = decode_json $response->content; - if ($response_info->{'data'}->{'description'} =~ /path or object not found: (.+)/) { + if ($response->status_line eq "500 Internal Server Error") { + $error = $response_info->{'data'}->{'exception'}; + } elsif ($response_info->{'data'}->{'description'} =~ /path or object not found: (.+)/) { $error = "path or object not found $1"; } else { $error = $response_info->{'data'}->{'description'}; @@ -493,29 +504,38 @@ sub rpower_response { my $response_info = decode_json $response->content; if ($node_info{$node}{cur_status} eq "RPOWER_ON_RESPONSE") { - xCAT::SvrUtils::sendmsg("on", $callback, $node); + if ($response_info->{'message'} eq "200 OK") { + xCAT::SvrUtils::sendmsg("on", $callback, $node); + } } if ($node_info{$node}{cur_status} eq "RPOWER_OFF_RESPONSE") { - xCAT::SvrUtils::sendmsg("off", $callback, $node); + if ($response_info->{'message'} eq "200 OK") { + xCAT::SvrUtils::sendmsg("off", $callback, $node); + } } - if ($node_info{$node}{cur_status} eq "RPOWER_STATUS_RESPONSE") { - xCAT::SvrUtils::sendmsg($response_info->{'data'}->{system_state}, $callback, $node); + if ($node_info{$node}{cur_status} eq "RPOWER_RESET_RESPONSE") { + if ($response_info->{'message'} eq "200 OK") { + xCAT::SvrUtils::sendmsg("reset", $callback, $node); + } + } + + if ($node_info{$node}{cur_status} eq "RPOWER_STATUS_RESPONSE") { + xCAT::SvrUtils::sendmsg($response_info->{'data'}->{CurrentHostState}, $callback, $node); } if ($next_status{ $node_info{$node}{cur_status} }) { if ($node_info{$node}{cur_status} eq "RPOWER_STATUS_RESPONSE") { - if ($response_info->{'data'}->{system_state} =~ /HOST_POWERED_ON/) { - $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{ON}; - } else { + if ($response_info->{'data'}->{CurrentHostState} =~ /Off$/) { $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{OFF}; + } else { + $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{ON}; } } else { $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }; } gen_send_request($node); - } else { $wait_node_num--; } @@ -523,6 +543,18 @@ sub rpower_response { return; } +#------------------------------------------------------- + +=head3 rinv_response + + Deal with response of rinv command + Input: + $node: nodename of current response + $response: Async return response + +=cut + +#------------------------------------------------------- sub rinv_response { my $node = shift; my $response = shift; From 96e453ee7af2c99f77f31014a76e9e15f753478f Mon Sep 17 00:00:00 2001 From: XuWei Date: Mon, 13 Mar 2017 01:47:41 -0400 Subject: [PATCH 6/7] add environment variable OPENBMC_DEVEL --- xCAT-server/lib/xcat/plugins/openbmc.pm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index a784d54e4..ba3217b29 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -22,6 +22,8 @@ use File::Basename; use Data::Dumper; use JSON; +$::OPENBMC_DEVEL = $ENV{'OPENBMC_DEVEL'}; + #------------------------------------------------------- =head3 handled_commands @@ -148,6 +150,13 @@ sub preprocess_request { $callback = shift; +#------------------------------------------------------- + if ($::OPENBMC_DEVEL ne "YES") { + #xCAT::SvrUtils::sendmsg("OPENBMC_DEVEL is $::OPENBMC_DEVEL", $callback); + return; + } +#------------------------------------------------------- + my $command = $request->{command}->[0]; my $noderange = $request->{node}; my $extrargs = $request->{arg}; From db05a2fa5259ec4af433b5b21b911f6fc0db4eef Mon Sep 17 00:00:00 2001 From: XuWei Date: Mon, 13 Mar 2017 21:50:17 -0400 Subject: [PATCH 7/7] modified depending on commments --- xCAT-server/lib/xcat/plugins/openbmc.pm | 28 ++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index ba3217b29..d25dbb218 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -150,13 +150,6 @@ sub preprocess_request { $callback = shift; -#------------------------------------------------------- - if ($::OPENBMC_DEVEL ne "YES") { - #xCAT::SvrUtils::sendmsg("OPENBMC_DEVEL is $::OPENBMC_DEVEL", $callback); - return; - } -#------------------------------------------------------- - my $command = $request->{command}->[0]; my $noderange = $request->{node}; my $extrargs = $request->{arg}; @@ -254,6 +247,11 @@ sub parse_args { my $command = shift; my $extrargs = shift; + my $check = unsupported($callback); + if (ref($check) eq "ARRAY") { + return $check; + } + $next_status{LOGIN_REQUEST} = "LOGIN_RESPONSE"; if ($command eq "rpower") { @@ -307,16 +305,26 @@ sub parse_args { $next_status{RINV_REQUEST} = "RINV_RESPONSE"; $status_info{RINV_RESPONSE}{argv} = "$subcommand"; } else { - return ([ 1, "Only 'cpu','dimm', 'bios','all' are supportted at the same time" ]); + return ([ 1, "Only 'cpu','dimm', 'bios','all' are supportted currently" ]); } } - print Dumper(%next_status) . "\n"; + print Dumper(\%next_status) . "\n"; return; } +sub unsupported { + my $callback = shift; + if ($::OPENBMC_DEVEL ne "YES") { + return ([ 1, "This function is currently not supported" ]); + } else { + xCAT::SvrUtils::sendmsg("Warning: Currently running development code, use at your own risk\n", $callback); + return; + } +} + #------------------------------------------------------- =head3 parse_node_info @@ -364,7 +372,7 @@ sub parse_node_info { } } - print Dumper(%node_info) ."\n"; + print Dumper(\%node_info) ."\n"; return; }