diff --git a/perl-xCAT/xCAT/FSPcfg.pm b/perl-xCAT/xCAT/FSPcfg.pm index 0d52c889d..a3a10e853 100644 --- a/perl-xCAT/xCAT/FSPcfg.pm +++ b/perl-xCAT/xCAT/FSPcfg.pm @@ -4,6 +4,8 @@ package xCAT::FSPcfg; use strict; use Getopt::Long; use xCAT::Usage; +use xCAT::Utils; +use xCAT::PPCcfg; #use Data::Dumper; #use xCAT::PPCcli; @@ -134,6 +136,15 @@ sub parse_args { foreach my $arg ( @ARGV ) { my ($command,$value) = split( /=/, $arg ); if ( !grep( /^$command$/, @$supported) and !$opt{resetnet}) { + my @enableASMI = xCAT::Utils->get_site_attribute("enableASMI"); + if (defined($enableASMI[0])) { + $enableASMI[0] =~ tr/a-z/A-Z/; # convert to upper + if (($enableASMI[0] eq "1") || ($enableASMI[0] eq "YES")) + { + $request->{enableASMI} = 1; + return xCAT::PPCcfg::parse_args($request, @_); + } + } return(usage( "Invalid command for $request->{hwtype} : $arg" )); } if ( exists( $cmds{$command} )) { diff --git a/perl-xCAT/xCAT/PPCcfg.pm b/perl-xCAT/xCAT/PPCcfg.pm index cbb8f89b1..74d92ee54 100644 --- a/perl-xCAT/xCAT/PPCcfg.pm +++ b/perl-xCAT/xCAT/PPCcfg.pm @@ -45,6 +45,8 @@ sub parse_args { "*_passwd", "hostname", "resetnet", + "dev", + "celogin1" ); my @bpa = ( "frame", @@ -156,6 +158,12 @@ sub parse_args { } } } + { + my $result = parse_dev_option( $request, \%cmds); + if ($result) { + return ( usage($result)); + } + } #################################### # Return method to invoke #################################### @@ -194,6 +202,24 @@ sub parse_args { } +sub parse_dev_option{ + my $req = shift; + my $cmds = shift; + foreach my $cmd (keys %$cmds) { + if ( $cmd =~ /^(dev|celogin1)$/ ) { + if ($cmds->{$cmd} and ($cmds->{$cmd} !~ /^(enable|disable)$/i) ) { + return( "Invalid argument ".$cmds->{$cmd}." for ".$cmd ); + } + $req->{dev} = 1; + } else { + $req->{other} = 1; + } + } + if ($req->{dev} eq '1' && $req->{other} eq '1') { + return ("Invalid command arrays"); + } + return undef; +} ########################################################################## # Parse the command line optional arguments ########################################################################## diff --git a/perl-xCAT/xCAT/PPCfsp.pm b/perl-xCAT/xCAT/PPCfsp.pm index 86e920d2b..b550968ad 100644 --- a/perl-xCAT/xCAT/PPCfsp.pm +++ b/perl-xCAT/xCAT/PPCfsp.pm @@ -9,6 +9,7 @@ use HTML::Form; use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR); use xCAT::Usage; use Socket; +use xCAT::PPCdb; ########################################## @@ -35,7 +36,9 @@ my %cmds = ( autopower => ["Auto Power Restart", \&autopower], sysdump => ["System Dump", \&sysdump], spdump => ["Service Processor Dump", \&spdump], - network => ["Network Configuration", \&netcfg]}, + network => ["Network Configuration", \&netcfg], + dev => ["Service Processor Command Line", \&devenable], + celogin1 => ["Service Processor Command Line", \&ce1enable]}, ); @@ -62,8 +65,9 @@ sub handler { foreach ( @$result ) { my %output; - $output{node}->[0]->{name}->[0] = $server; - $output{node}->[0]->{data}->[0]->{contents}->[0] = @$_[1]; + $output{node}->[0]->{name}->[0] = $request->{host}; + $output{node}->[0]->{data}->[0]->{contents}->[0] = $server. ": ".@$_[1]; + $output{node}->[0]->{cmd}->[0] = @$_[2]; $output{errorcode} = @$_[0]; push @outhash, \%output; } @@ -79,6 +83,14 @@ sub handler { ########################################################################## # Logon through remote FSP HTTP-interface ########################################################################## +my %logonname = ( + hmc => ["hscroot","abc123"], + ivm => ["padmin", "padmin"], + fsp => ["admin", "admin"], + bpa => ["admin", "admin"], + frame => ["admin", "admin"], + cec => ["admin", "admin"], + ); sub connect { my $req = shift; @@ -97,7 +109,14 @@ sub connect { # Get userid/password ################################## my $cred = $req->{$server}{cred}; - + my $name = undef; + if (($req->{dev} eq '1') or + ($req->{command} eq 'rpower')) { + $name = "celogin"; + } else { + $name = $logonname{$req->{hwtype}}->[0]; + } + my @cred = xCAT::PPCdb::credentials($server, $req->{hwtype}, $name); ################################## # Redirect STDERR to variable ################################## @@ -146,8 +165,8 @@ sub connect { # Submit logon ################################## my $res = $ua->post( $url, - [ user => @$cred[0], - password => @$cred[1], + [ user => @cred[0], + password => @cred[1], lang => "0", submit => "Log in" ] ); @@ -176,7 +195,7 @@ sub connect { ############################## return( $ua, $server, - @$cred[0], + @cred[0], \$lwp_log ); } ############################## @@ -196,11 +215,116 @@ sub connect { return( $lwp_log."Logon failure" ); } +sub ce1enable { + return &loginenable($_[0], $_[1], $_[2], "celogin1"); +} +sub devenable { + return &loginenable($_[0], $_[1], $_[2], "dev"); +} +my %cmdline_for_log = ( + dev => { + enable => "registry -Hw nets/DevEnabled 1", + disable => "registry -Hw nets/DevEnabled 0", + check_pwd => "registry -l DevPwdFile", + create_pwd => "netsDynPwdTool --create dev FipSdev", + password => "FipSdev" + }, + celogin1 => { + enable => "registry -Hw nets/CE1Enabled 1", + disable => "registry -Hw nets/CE1Enabled 0", + check_pwd => "registry -l Ce1PwdFile", + create_pwd => "netsDynPwdTool --create celogin1 FipSce1", + password => "FipSce1" + }, + ); +sub send_command { + my $ua = shift; + my $server = shift; + my $id = shift; + my $log_name = shift; + my $cmd = shift; + my $cmd_line = $cmdline_for_log{$log_name}{$cmd}; + if (!defined($cmd_line)) { + return undef; + } + my $res = $ua->post( "https://$server/cgi-bin/cgi", + [ form => $id, + cmd => $cmd_line, + submit => "Execute" ] + ); -########################################################################## -# Logoff through remote FSP HTTP-interface -########################################################################## + if ( !$res->is_success() ) { + return undef; + } + if ( $res->content =~ /(not allowed.*\.|Invalid entry)/ ) { + return undef; + } + return $res->content; +} +sub loginstate { + my $ua = shift; + my $server = shift; + my $log_name = shift; + my $url = "https://$server/cgi-bin/cgi?form=4"; + my $res = $ua->get($url); + if (!$res->is_success()) { + return ([RC_ERROR, $res->status_line]); + } + if ($res->content =~ m#$log_name(\w+)#) { + my $out = sprintf("%9s: %8s", $log_name, $1); + return ( [SUCCESS, $out]); + } else { + return ( [RC_ERROR, "not found status for $log_name"]); + } +} + +sub loginenable { + my $exp = shift; + my $request = shift; + my $id = shift; + my $log_name = shift; + my $ua = @$exp[0]; + my $server = @$exp[1]; + + my $value = $request->{method}{$log_name}; + if (!defined($value)) { + return &loginstate($ua, $server, $log_name); + } + my $url = "https://$server/cgi-bin/cgi?form=$id"; + my $res = $ua->get( $url ); + if (!$res->is_success()) { + return( [RC_ERROR,$res->status_line] ); + } + + $res = &send_command($ua, $server, $id, $log_name, $value); + if (!defined($res)) { + return ([RC_ERROR, "Send command Failed"]); + } + if ( $value =~ m/^disable$/ ) { + my $out = sprintf("%9s: Disabled", $log_name); + return( [SUCCESS, $out] ); + } +#check password# + $res = &send_command($ua, $server, $id, $log_name, "check_pwd"); + if (!defined($res)) { + return ([RC_ERROR, "Send command Failed"]); + } + my $password = undef; + if ($res =~ m/\[\d+([a-zA-Z]+)\d+\]/) { + $password = $1; + } else { +# create password # + $res = &send_command($ua, $server, $id, $log_name, "create_pwd"); + if (!defined($res)) { + return ([RC_ERROR, "Send command Failed"]); + } + $password = $cmdline_for_log{$log_name}{password}; + print "create password for $log_name is '$cmdline_for_log{$log_name}{password}'\n"; + } + my $out = sprintf("%9s: Enabled, password: $password", $log_name); + return( [SUCCESS, $out] ); +} sub disconnect { my $exp = shift; @@ -276,6 +400,7 @@ sub process_cmd { # Run command ################################## my $res = $cmds{$command}{$_}[1]($exp, $request, $form, \%menu); + push @$res, $_; push @result, $res; } return( \@result ); diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 19930eb0f..9658e38d0 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -1558,6 +1558,15 @@ my @nodeattrs = ( only_if => 'mgt=fsp', tabentry => 'ppcdirect.password', access_tabentry => 'ppcdirect.hcp=attr:node::ppcdirect.username=str:general', + }, + {attr_name => 'passwd.celogin', + only_if => 'mgt=fsp', + tabentry => 'ppcdirect.password', + access_tabentry => 'ppcdirect.hcp=attr:node::ppcdirect.username=str:celogin', + }, {attr_name => 'passwd.celogin', + only_if => 'mgt=bpa', + tabentry => 'ppcdirect.password', + access_tabentry => 'ppcdirect.hcp=attr:node::ppcdirect.username=str:celogin', }, {attr_name => 'passwd.HMC', only_if => 'mgt=bpa', diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index d5e54d4f4..e58dfeb4d 100644 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -132,7 +132,12 @@ my %usage = ( rspconfig frame=<*|frame> HMC specific: rspconfig [sshcfg] - rspconfig [sshcfg=]", + rspconfig [sshcfg=] + FSP/CEC Specific: + rspconfig [dev|celogin1] + rspconfig [dev=]| + rspconfig [celogin1=] + ", "getmacs" => "Usage: Common: diff --git a/xCAT-server/lib/perl/xCAT/PPC.pm b/xCAT-server/lib/perl/xCAT/PPC.pm index 2ad9ea066..15ccf5542 100644 --- a/xCAT-server/lib/perl/xCAT/PPC.pm +++ b/xCAT-server/lib/perl/xCAT/PPC.pm @@ -1241,6 +1241,210 @@ sub fork_cmd { } return(0); } +sub handle_cmd { + my $server = shift; + my $host = shift; + my $request = shift; + my $verbose = $request->{verbose}; + eval { require xCAT::PPCfsp }; + if ( $@ ) { + send_msg( $request, 1, $@ ); + return; + } + my @exp = xCAT::PPCfsp::connect( $request, $server ); + +#################################### +# Error connecting +#################################### + if ( ref($exp[0]) ne "LWP::UserAgent" ) { +#send_msg( $request, 1, $exp[0] ); + my @output_array; + my $methods = $request->{method}; + foreach ( keys %$methods) { + my %output; + $output{node}->[0]->{name}->[0] = "$host"; + $output{node}->[0]->{data}->[0]->{contents}->[0] = "$server: $exp[0]"; + $output{node}->[0]->{cmd}->[0] = $_; + $output{errorcode} = 128; + push @output_array, \%output; + } + return \@output_array; + } + $request->{host} = $host; + my $result = xCAT::PPCfsp::handler( $server, $request, \@exp); + +#################################### +# Output verbose Perl::LWP +#################################### + if ( $verbose ) { + my $verbose_log = $exp[3]; + my $output = shift @$result; + $output->{data} = [$$verbose_log]; + unshift @$result, \%$output; + } + return $result; +} + +sub handle_find_hw_children { + my $host = shift; + my $child_type = shift; + my @children = (); + my $vpdtab = xCAT::Table->new("vpd"); + if (!defined($vpdtab) or !defined($child_type)) { + return undef; + } + my $mtms = $vpdtab->getAttribs({node=>$host}, qw(serial mtm)); + if (!defined($mtms)) { + return undef; + } + my @nodearray = $vpdtab->getAttribs({serial=>$mtms->{serial}, mtm=>$mtms->{mtm}}, qw(node side)); + if (!defined(@nodearray)) { + return undef; + } + foreach my $node (@nodearray) { + my $n_type = xCAT::DBobjUtils->getnodetype($node->{node}); + if ($n_type !~ /^$child_type$/ or !defined($node->{side})) { + next; + } + push @children, $node; + } + if (scalar(@children) eq '0') { + return undef; + } + return \@children; +} +sub print_res { + my $request = shift; + my $host = shift; + my $res_array = shift; + if (!defined($res_array) or ref($res_array) ne 'ARRAY') { + return; + } + my $out = $request->{pipe}; + print $out freeze( $res_array ); + print $out "\nENDOFFREEZE6sK4ci\n"; + return ; +} + +sub get_dirindex_from_side { + my $side = shift; + my $dir = undef; + if ($side =~ /(a+)-\d*/i) { + $dir = '0'; + } elsif ($side =~ /(b+)-\d*/i) { + $dir = '1'; + } else { + $dir = '2'; + } + return $dir; +} +sub reorgnize_res_for_handle_cmd { + my $request = shift; + my $host = shift; + my $output = shift; + my $methods = $request->{method}; + my %re_output = (); + my %succ_side = (); + my $dir = undef; + foreach my $side (keys %$output) { + my $res = $output->{$side}; + foreach my $index (@$$res) { + $dir = &get_dirindex_from_side($side); + my $cmd = $index->{node}->[0]->{cmd}->[0]; + if (($index->{node}->[0]->{data}->[0]->{contents}->[0]) =~ /feature is not available/) { + $dir = '0'; + } + if (!defined($succ_side{$cmd}{$dir}{done})) { + if (defined($re_output{$cmd}{$dir})) { + my $array = $re_output{$cmd}{$dir}; + my $n = scalar(@$array); + $array->[$n] = $index; + } else { + $re_output{$cmd}{$dir}[0] = $index; + } + } else { + next; + } + if ($index->{errorcode} eq '0') { + @{$re_output{$cmd}{$dir}} = (); + $re_output{$cmd}{$dir}[0] = $index; + $succ_side{$cmd}{$dir}{done}++; + } + } + } + foreach my $method (keys %re_output) { + my $value = $re_output{$method}; + foreach my $side (keys %$value) { + my $res_array = $value->{$side}; + &print_res($request, $host, $res_array); + } + } + return undef; +} + +sub process_children { + my $request = shift; + my $host = shift; + my $node_array = shift; + my %output = (); + my %conn_flag = (); + foreach my $index (@$node_array) { + my $side = $index->{side}; + my $dir = &get_dirindex_from_side($side); + if (defined($conn_flag{$dir})) { + next; + } + my $res = &handle_cmd($index->{node}, $host, $request); + $output{$side} = \$res; + if ($res->[0]->{errorcode} ne '128') { + $conn_flag{$dir} = 1; + } + } + &reorgnize_res_for_handle_cmd($request, $host, \%output); + return undef; +} + + +my %children_type = ( + cec => "fsp", + frame => "bpa" + ); + +sub handle_redundance_fsps { + my $host = shift; + my $hwtype = shift; + my $request = shift; + my $res = undef; + if ($hwtype =~ /^(bpa|fsp)$/) { + $res = &handle_cmd($host, $host, $request); + &print_res($request, $host, $res); + } elsif ($hwtype =~ /^(cec|frame)$/){ + my $child_type = $children_type{$hwtype}; + my $children = &handle_find_hw_children($host, $child_type); + if (!defined($children)) { + send_msg($request, 1, "Not found any $child_type for $host"); + } else { + &process_children($request, $host, $children); + } + } else { + send_msg( $request, 1, "$hwtype not support!"); + } + return undef; +} +sub check_node_info { + my $hash = shift; + my $if_lpar = undef; + while (my ($mtms, $h) = each(%$hash)) { + while (my($name, $d) = each(%$h)) { + my $node_type = @$d[4]; + if ($node_type =~ /^lpar$/) { + $if_lpar = $name; + last; + } + } + } + return $if_lpar; +} ########################################################################## @@ -1286,48 +1490,30 @@ sub invoke_cmd { ######################################## # Direct-attached FSP handler ######################################## - if ( ($power ne "hmc") && ( $hwtype eq "fsp" or $hwtype eq "bpa" or $hwtype eq "cec") && $request->{fsp_api} == 0) { + if ( ($power ne "hmc") && ( $hwtype =~ /^(fsp|bpa|cec|frame)$/) && $request->{fsp_api} == 0) { - #################################### - # Dynamically load FSP module - #################################### - eval { require xCAT::PPCfsp }; - if ( $@ ) { - send_msg( $request, 1, $@ ); - return; + if ($request->{command} eq 'rpower') { + my $check = &check_node_info($nodes); + if (defined($check)) { + my %output; + $output{node}->[0]->{name}->[0] = $check; + $output{node}->[0]->{data}->[0]->{contents}->[0] = "Error: $request->{command} not support on lpar in ASMI mode"; + $output{node}->[0]->{cmd}->[0] = $request->{method}; + $output{errorcode} = 1; + my $out = $request->{pipe}; + print $out freeze( [\%output] ); + print $out "\nENDOFFREEZE6sK4ci\n"; + return ; + } + + if (ref($request->{method}) ne 'HASH') { + my %method_hash = (); + my $method = $request->{method}; + $method_hash{$method} = undef; + $request->{method} = \%method_hash; } - my @exp = xCAT::PPCfsp::connect( $request, $host ); - - #################################### - # Error connecting - #################################### - if ( ref($exp[0]) ne "LWP::UserAgent" ) { - #send_msg( $request, 1, $exp[0] ); - my %output; - $output{node}->[0]->{name}->[0] = $host; - $output{node}->[0]->{data}->[0]->{contents}->[0] = "$exp[0]"; - $output{errorcode} = 1; - push @outhash, \%output; - my $out = $request->{pipe}; - print $out freeze( [@outhash] ); - print $out "\nENDOFFREEZE6sK4ci\n"; - return; } - my $result = xCAT::PPCfsp::handler( $host, $request, \@exp ); - - #################################### - # Output verbose Perl::LWP - #################################### - if ( $verbose ) { - $verbose_log = $exp[3]; - - my %output; - $output{data} = [$$verbose_log]; - unshift @$result, \%output; - } - my $out = $request->{pipe}; - print $out freeze( $result ); - print $out "\nENDOFFREEZE6sK4ci\n"; + &handle_redundance_fsps($host, $hwtype, $request); return; } @@ -1770,6 +1956,7 @@ sub process_request { $request->{stdin} = $req->{stdin}->[0]; $request->{method} = $req->{method}->[0]; $request->{op} = $req->{op}->[0]; + $request->{enableASMI} = $req->{enableASMI}; #support more options in hierachy if( ref( $req->{opt}) eq 'ARRAY' ) { my $h = $req->{opt}->[0]; @@ -1894,37 +2081,44 @@ sub process_request { $request_new->{node} = \@next; $request_new->{fsp_api} = 0; if($lasthcp_type =~ /^(fsp|bpa|cec|frame)$/ ) { - #my $fsp_api = check_fsp_api($request); - #if($fsp_api == 0 ) { - $request_new->{fsp_api} = 1; - # } +#my $fsp_api = check_fsp_api($request); +#if($fsp_api == 0 ) { + $request_new->{fsp_api} = 1; +# } } - #For mkhwconn .... +#For mkhwconn .... if( $request->{hwtype} ne 'hmc' ) { $request_new->{hwtype} = $lasthcp_type; } else { $request_new->{fsp_api} = 0; } - #print Dumper($request_new); +#print Dumper($request_new); @failed_nodes = () ; +#For rspconfig to use ASMI + if (defined($request->{enableASMI}) && ($request->{enableASMI} eq "1")) { + $request_new->{fsp_api} = 0; + } process_command( $request_new , \%hcps_will, \@failed_nodes, \%failed_msg); - #print "after result:\n"; - #print Dumper(\@failed_nodes); - if($lasthcp_type =~ /^(fsp|bpa|cec)$/ && $request->{hwtype} ne 'hmc' ) { - my @enableASMI = xCAT::Utils->get_site_attribute("enableASMI"); - if (defined($enableASMI[0])) { - $enableASMI[0] =~ tr/a-z/A-Z/; # convert to upper - if (($enableASMI[0] eq "1") || ($enableASMI[0] eq "YES")) - { - #through asmi ...... - $request_new->{fsp_api} = 0; - if(@failed_nodes != 0) { - my @temp = @failed_nodes; - @failed_nodes = (); - $request_new->{node} = \@temp; - process_command( $request_new , \%hcps_will, \@failed_nodes, \%failed_msg); - } #end of if - } # end of if +#print "after result:\n"; +#print Dumper(\@failed_nodes); + if($lasthcp_type =~ /^(fsp|bpa|cec|frame)$/ && + $request->{hwtype} ne 'hmc' && + $request_new->{fsp_api} ne '0') { + if ($request_new->{command} =~ /^(rspconfig|rpower|reventlog)$/){ + my @enableASMI = xCAT::Utils->get_site_attribute("enableASMI"); + if (defined($enableASMI[0])) { + $enableASMI[0] =~ tr/a-z/A-Z/; # convert to upper + if (($enableASMI[0] eq "1") || ($enableASMI[0] eq "YES")) { + #through asmi ...... + $request_new->{fsp_api} = 0; + if(@failed_nodes != 0) { + my @temp = @failed_nodes; + @failed_nodes = (); + $request_new->{node} = \@temp; + process_command( $request_new , \%hcps_will, \@failed_nodes, \%failed_msg); + } #end of if + } #end of if + } # end of if } #end of if } #end of if } #end of while(1)