From bc5663b911bcfb5e5d69cab557b8f14eefcab871 Mon Sep 17 00:00:00 2001 From: XuWei Date: Fri, 5 May 2017 02:30:08 -0400 Subject: [PATCH 1/4] Enhance bmcdisocver to support openbmc --- perl-xCAT/xCAT/Schema.pm | 5 ++ xCAT-server/lib/xcat/plugins/bmcdiscover.pm | 95 +++++++++++++++++++-- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 0e5fd1dce..bf4816595 100755 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -2305,6 +2305,11 @@ my @nodeattrs = ( tabentry => 'mp.nodetype', access_tabentry => 'mp.node=attr:node', }, + { attr_name => 'hwtype', + only_if => 'mgt=openbmc', + tabentry => 'mp.nodetype', + access_tabentry => 'mp.node=attr:node', + }, { attr_name => 'supernode', tabentry => 'ppc.supernode', access_tabentry => 'ppc.node=attr:node', diff --git a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm index d05a44ef5..b4365397a 100644 --- a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm @@ -29,6 +29,7 @@ use Data::Dumper; use File::Basename; use File::Path; use Cwd; +use JSON; my $nmap_path; @@ -575,7 +576,18 @@ sub scan_process { # Set child process default, if not the function runcmd may return error $SIG{CHLD} = 'DEFAULT'; - bmcdiscovery_ipmi(${$live_ip}[$i], $opz, $opw, $request_command); + + my $nmap_cmd = "nmap ${$live_ip}[$i] -p 2200 -Pn"; + my $nmap_output = xCAT::Utils->runcmd($nmap_cmd, -1); + if ($nmap_output =~ /2200\/tcp (\w+)/) { + my $port_stat = $1; + if ($port_stat eq "open") { + bmcdiscovery_openbmc(${$live_ip}[$i], $opz, $opw, $request_command); + } else { + bmcdiscovery_ipmi(${$live_ip}[$i], $opz, $opw, $request_command); + } + } + exit 0; } else { @@ -625,14 +637,15 @@ sub scan_process { sub format_stanza { my $node = shift; my $data = shift; + my $mgt_type = shift; my ($bmcip, $bmcmtm, $bmcserial, $bmcuser, $bmcpass, $nodetype, $hwtype) = split(/,/, $data); my $result; if (defined($bmcip)) { $result .= "$node:\n\tobjtype=node\n"; $result .= "\tgroups=all\n"; $result .= "\tbmc=$bmcip\n"; - $result .= "\tcons=ipmi\n"; - $result .= "\tmgt=ipmi\n"; + $result .= "\tcons=$mgt_type\n"; + $result .= "\tmgt=$mgt_type\n"; if ($bmcmtm) { $result .= "\tmtm=$bmcmtm\n"; } @@ -665,11 +678,12 @@ sub format_stanza { sub write_to_xcatdb { my $node = shift; my $data = shift; + my $mgt_type = shift; my ($bmcip, $bmcmtm, $bmcserial, $bmcuser, $bmcpass, $nodetype, $hwtype) = split(/,/, $data); my $request_command = shift; my $ret; - $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => [ '-t', 'node', '-o', $node, "bmc=$bmcip", "cons=ipmi", "mgt=ipmi", "mtm=$bmcmtm", "serial=$bmcserial", "bmcusername=$bmcuser", "bmcpassword=$bmcpass", "nodetype=$nodetype", "hwtype=$hwtype", "groups=all" ] }, $request_command, 0, 1); + $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => [ '-t', 'node', '-o', $node, "bmc=$bmcip", "cons=$mgt_type", "mgt=$mgt_type", "mtm=$bmcmtm", "serial=$bmcserial", "bmcusername=$bmcuser", "bmcpassword=$bmcpass", "nodetype=$nodetype", "hwtype=$hwtype", "groups=all" ] }, $request_command, 0, 1); if ($::RUNCMD_RC != 0) { my $rsp = {}; push @{ $rsp->{data} }, "create or modify node is failed.\n"; @@ -962,10 +976,10 @@ sub bmcdiscovery_ipmi { } if (defined($opz) || defined($opw)) { - format_stanza($node, $ip); + format_stanza($node, $ip, "ipmi"); if (defined($opw)) { - write_to_xcatdb($node, $ip, $request_command); + write_to_xcatdb($node, $ip, "ipmi", $request_command); } } else { @@ -976,4 +990,73 @@ sub bmcdiscovery_ipmi { } } +#----------------------------------------------------------------------------- + +=head3 bmcdiscovery_openbmc + + Support for discovering bmc using openbmc + Returns: + if it is openbmc, it returns bmc ip or host; + if it is not openbmc, it returns nothing; + +=cut + +#----------------------------------------------------------------------------- +sub bmcdiscovery_openbmc{ + my $ip = shift; + my $opz = shift; + my $opw = shift; + my $request_command = shift; + my $node = sprintf("node-%08x", unpack("N*", inet_aton($ip))); + + my $cjar_file = "/tmp/cjar_$ip"; + my $data = '{"data": [ "' . $bmc_user .'", "' . $bmc_pass . '" ] }'; + + my $output = `curl -c $cjar_file -k -X POST -H \"Content-Type: application/json\" -d '$data' https://$ip/login`; + + my $login_rsp = decode_json $output; + if ($login_rsp->{status} eq "ok") { + my $req_output = `curl -b $cjar_file -k https://$ip/xyz/openbmc_project/inventory/system/chassis/motherboard`; + my $response = decode_json $req_output; + my $mtm = $response->{data}->{Model}; + my $serial = $response->{data}->{SerialNumber}; + $mtm =~ s/^\s+|\s+$//g; + $serial =~ s/^\s+|\s+$//g; + + $ip .= ",$mtm"; + $ip .= ",$serial"; + if ($::opt_P) { + if ($::opt_U) { + $ip .= ",$::opt_U,$::opt_P"; + } else { + $ip .= ",,$::opt_P"; + } + } else { + $ip .= ",,"; + } + $ip .= ",mp,bmc"; + if ($mtm and $serial) { + $node = "node-$mtm-$serial"; + $node =~ s/(.*)/\L$1/g; + $node =~ s/[\s:\._]/-/g; + } + + `rm -f $cjar_file`; + } else { + xCAT::MsgUtils->message("E", { data => ["$login_rsp->{data}->{description}"] }, $::CALLBACK); + return 1; + } + + if (defined($opz) || defined($opw)) { + format_stanza($node, $ip, "openbmc"); + if (defined($opw)) { + write_to_xcatdb($node, $ip, "openbmc", $request_command); + } + } else { + my $rsp = {}; + push @{ $rsp->{data} }, "$ip"; + xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); + } +} + 1; From 2155d8c33d792222b1eff07697c0e7e9966acadb Mon Sep 17 00:00:00 2001 From: XuWei Date: Sun, 7 May 2017 22:20:04 -0400 Subject: [PATCH 2/4] modified depending on comments --- xCAT-server/lib/xcat/plugins/bmcdiscover.pm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm index b4365397a..8ddecdb85 100644 --- a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm @@ -586,6 +586,9 @@ sub scan_process { } else { bmcdiscovery_ipmi(${$live_ip}[$i], $opz, $opw, $request_command); } + } else { + xCAT::MsgUtils->message("E", "Can not get status of 2200 port.", $::CALLBACK); + exit 1; } exit 0; @@ -683,7 +686,12 @@ sub write_to_xcatdb { my $request_command = shift; my $ret; - $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => [ '-t', 'node', '-o', $node, "bmc=$bmcip", "cons=$mgt_type", "mgt=$mgt_type", "mtm=$bmcmtm", "serial=$bmcserial", "bmcusername=$bmcuser", "bmcpassword=$bmcpass", "nodetype=$nodetype", "hwtype=$hwtype", "groups=all" ] }, $request_command, 0, 1); + $ret = xCAT::Utils->runxcmd({ command => ['chdef'], + arg => [ '-t', 'node', '-o', $node, "bmc=$bmcip", "cons=$mgt_type", + "mgt=$mgt_type", "mtm=$bmcmtm", "serial=$bmcserial", + "bmcusername=$bmcuser", "bmcpassword=$bmcpass", "nodetype=$nodetype", + "hwtype=$hwtype", "groups=all" ] }, + $request_command, 0, 1); if ($::RUNCMD_RC != 0) { my $rsp = {}; push @{ $rsp->{data} }, "create or modify node is failed.\n"; @@ -1020,9 +1028,12 @@ sub bmcdiscovery_openbmc{ my $response = decode_json $req_output; my $mtm = $response->{data}->{Model}; my $serial = $response->{data}->{SerialNumber}; + + # delete space before and after $mtm =~ s/^\s+|\s+$//g; $serial =~ s/^\s+|\s+$//g; + # format ip string for format_stanza function $ip .= ",$mtm"; $ip .= ",$serial"; if ($::opt_P) { @@ -1041,7 +1052,7 @@ sub bmcdiscovery_openbmc{ $node =~ s/[\s:\._]/-/g; } - `rm -f $cjar_file`; + unlink $cjar_file; } else { xCAT::MsgUtils->message("E", { data => ["$login_rsp->{data}->{description}"] }, $::CALLBACK); return 1; From 52e2e2ff752262d9eee29574bbd6d165a6fe3570 Mon Sep 17 00:00:00 2001 From: XuWei Date: Mon, 8 May 2017 03:24:44 -0400 Subject: [PATCH 3/4] modified depending on comments --- xCAT-server/lib/xcat/plugins/bmcdiscover.pm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm index 8ddecdb85..ee0742736 100644 --- a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm @@ -1020,10 +1020,9 @@ sub bmcdiscovery_openbmc{ my $cjar_file = "/tmp/cjar_$ip"; my $data = '{"data": [ "' . $bmc_user .'", "' . $bmc_pass . '" ] }'; - my $output = `curl -c $cjar_file -k -X POST -H \"Content-Type: application/json\" -d '$data' https://$ip/login`; + my $output = `curl -c $cjar_file -k -X POST -H \"Content-Type: application/json\" -d '$data' https://$ip/login`; - my $login_rsp = decode_json $output; - if ($login_rsp->{status} eq "ok") { + if ($output =~ /\"status\": \"ok\"/) { my $req_output = `curl -b $cjar_file -k https://$ip/xyz/openbmc_project/inventory/system/chassis/motherboard`; my $response = decode_json $req_output; my $mtm = $response->{data}->{Model}; @@ -1054,7 +1053,9 @@ sub bmcdiscovery_openbmc{ unlink $cjar_file; } else { - xCAT::MsgUtils->message("E", { data => ["$login_rsp->{data}->{description}"] }, $::CALLBACK); + if ($output =~ /\"description\": \"Invalid username or password\"/) { + xCAT::MsgUtils->message("E", { data => ["BMC username/password is incorrect for $ip"] }, $::CALLBACK); + } return 1; } From f9eef1d3d03b239214a4eca622b6977dead0d33c Mon Sep 17 00:00:00 2001 From: XuWei Date: Mon, 8 May 2017 21:28:32 -0400 Subject: [PATCH 4/4] modified depending on comments --- xCAT-server/lib/xcat/plugins/bmcdiscover.pm | 69 ++++++++++++--------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm index ee0742736..1aac3e0d9 100644 --- a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm @@ -718,7 +718,6 @@ sub write_to_xcatdb { sub send_rep { my $resp = shift; - unless ($resp) { return; } store_fd($resp, $parent_fd); } @@ -914,13 +913,15 @@ sub bmcdiscovery_ipmi { if ($bmc_pass) { $bmcpassword = "-P $bmc_pass"; } + + my $node_data = $ip; my $icmd = "/opt/xcat/bin/ipmitool-xcat -vv -I lanplus $bmcusername $bmcpassword -H $ip chassis status "; my $output = xCAT::Utils->runcmd("$icmd", -1); if ($output =~ $bmcstr) { if ($output =~ /RAKP 2 message indicates an error : (.+)\nError: (.+)/) { - xCAT::MsgUtils->message("E", { data => ["$2: $1 for $ip"] }, $::CALLBACK); - return 1; + xCAT::MsgUtils->message("W", { data => ["$2: $1 for $ip"] }, $::CALLBACK); + return; } # The output contains System Power indicated the username/password is correct, then try to get MTMS @@ -958,41 +959,41 @@ sub bmcdiscovery_ipmi { } } - $ip .= ",$mtm"; - $ip .= ",$serial"; + $node_data .= ",$mtm"; + $node_data .= ",$serial"; if ($::opt_P) { if ($::opt_U) { - $ip .= ",$::opt_U,$::opt_P"; + $node_data .= ",$::opt_U,$::opt_P"; } else { - $ip .= ",,$::opt_P"; + $node_data .= ",,$::opt_P"; } } else { - $ip .= ",,"; + $node_data .= ",,"; } - $ip .= ",mp,bmc"; + $node_data .= ",mp,bmc"; if ($mtm and $serial) { $node = "node-$mtm-$serial"; $node =~ s/(.*)/\L$1/g; $node =~ s/[\s:\._]/-/g; } } elsif ($output =~ /error : unauthorized name/) { - xCAT::MsgUtils->message("E", { data => ["BMC username is incorrect for $ip"] }, $::CALLBACK); - return 1; + xCAT::MsgUtils->message("W", { data => ["BMC username is incorrect for $ip"] }, $::CALLBACK); + return; } elsif ($output =~ /RAKP \S* \S* is invalid/) { - xCAT::MsgUtils->message("E", { data => ["BMC password is incorrect for $ip"] }, $::CALLBACK); - return 1; + xCAT::MsgUtils->message("W", { data => ["BMC password is incorrect for $ip"] }, $::CALLBACK); + return; } if (defined($opz) || defined($opw)) { - format_stanza($node, $ip, "ipmi"); + format_stanza($node, $node_data, "ipmi"); if (defined($opw)) { - write_to_xcatdb($node, $ip, "ipmi", $request_command); + write_to_xcatdb($node, $node_data, "ipmi", $request_command); } } else { my $rsp = {}; - push @{ $rsp->{data} }, "$ip"; + push @{ $rsp->{data} }, "$node_data"; xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); } } @@ -1017,6 +1018,7 @@ sub bmcdiscovery_openbmc{ my $request_command = shift; my $node = sprintf("node-%08x", unpack("N*", inet_aton($ip))); + my $node_data = $ip; my $cjar_file = "/tmp/cjar_$ip"; my $data = '{"data": [ "' . $bmc_user .'", "' . $bmc_pass . '" ] }'; @@ -1025,26 +1027,33 @@ sub bmcdiscovery_openbmc{ if ($output =~ /\"status\": \"ok\"/) { my $req_output = `curl -b $cjar_file -k https://$ip/xyz/openbmc_project/inventory/system/chassis/motherboard`; my $response = decode_json $req_output; - my $mtm = $response->{data}->{Model}; - my $serial = $response->{data}->{SerialNumber}; + my $mtm; + my $serial; + + if (defined($response->{data}) and defined($response->{data}->{Model}) and defined($response->{data}->{SerialNumber})) { + $mtm = $response->{data}->{Model}; + $serial = $response->{data}->{SerialNumber}; + } else { + return; + } # delete space before and after $mtm =~ s/^\s+|\s+$//g; $serial =~ s/^\s+|\s+$//g; - # format ip string for format_stanza function - $ip .= ",$mtm"; - $ip .= ",$serial"; + # format info string for format_stanza function + $node_data .= ",$mtm"; + $node_data .= ",$serial"; if ($::opt_P) { if ($::opt_U) { - $ip .= ",$::opt_U,$::opt_P"; + $node_data .= ",$::opt_U,$::opt_P"; } else { - $ip .= ",,$::opt_P"; + $node_data .= ",,$::opt_P"; } } else { - $ip .= ",,"; + $node_data .= ",,"; } - $ip .= ",mp,bmc"; + $node_data .= ",mp,bmc"; if ($mtm and $serial) { $node = "node-$mtm-$serial"; $node =~ s/(.*)/\L$1/g; @@ -1054,19 +1063,19 @@ sub bmcdiscovery_openbmc{ unlink $cjar_file; } else { if ($output =~ /\"description\": \"Invalid username or password\"/) { - xCAT::MsgUtils->message("E", { data => ["BMC username/password is incorrect for $ip"] }, $::CALLBACK); + xCAT::MsgUtils->message("W", { data => ["Invalid username or password for $ip"] }, $::CALLBACK); } - return 1; + return; } if (defined($opz) || defined($opw)) { - format_stanza($node, $ip, "openbmc"); + format_stanza($node, $node_data, "openbmc"); if (defined($opw)) { - write_to_xcatdb($node, $ip, "openbmc", $request_command); + write_to_xcatdb($node, $node_data, "openbmc", $request_command); } } else { my $rsp = {}; - push @{ $rsp->{data} }, "$ip"; + push @{ $rsp->{data} }, "$node_data"; xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); } }