1. Add support for unmanagement nodes
2. Add support for replace node's Provisioning MAC address 3. Enable specify rack/chassis info while import nodes and do nodes discovery. git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@13994 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -11,6 +11,7 @@ require xCAT::Table; | ||||
| require xCAT::TableUtils; | ||||
| require xCAT::NodeRange; | ||||
| require xCAT::NetworkUtils; | ||||
| require xCAT::DBobjUtils; | ||||
|  | ||||
|  | ||||
| #-------------------------------------------------------------------------------- | ||||
| @@ -203,8 +204,8 @@ sub rackformat_to_numricformat{ | ||||
|     my ($class, $format, $rackname) = @_; | ||||
|     my ($prefix, $appendix, $len) = xCAT::ProfiledNodeUtils->split_hostname($format, 'R'); | ||||
|  | ||||
|     my $objhash = xCAT::DBojbutils->getobjdefs({$rackname, "rack"}); | ||||
|     my $racknum = $objhash->{$rackname}->{"num"}; | ||||
|     my %objhash = xCAT::DBobjUtils->getobjdefs({$rackname, "rack"}); | ||||
|     my $racknum = $objhash{$rackname}{"num"}; | ||||
|     my $maxnum = 10 ** $len; | ||||
|     my $fullnum = $maxnum + $racknum; | ||||
|     return $prefix.(substr $fullnum, 1).$appendix; | ||||
| @@ -344,7 +345,7 @@ sub get_output_filename | ||||
|       Description : Get all chassis in system. | ||||
|       Arguments   : hashref: if not set, return a array ref. | ||||
|                              if set, return a hash ref. | ||||
|       Returns     : ref for node list. | ||||
|       Returns     : ref for chassis list. | ||||
|       Example     :  | ||||
|                     my $arrayref = xCAT::ProfiledNodeUtils->get_all_chassis(); | ||||
|                     my $hashref = xCAT::ProfiledNodeUtils->get_all_chassis(1); | ||||
| @@ -370,6 +371,45 @@ sub get_all_chassis | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
|  | ||||
| =head3 get_all_rack | ||||
|       Description : Get all rack in system. | ||||
|       Arguments   : hashref: if not set, return a array ref. | ||||
|                              if set, return a hash ref. | ||||
|       Returns     : ref for rack list. | ||||
|       Example     :  | ||||
|                     my $arrayref = xCAT::ProfiledNodeUtils->get_all_rack(); | ||||
|                     my $hashref = xCAT::ProfiledNodeUtils->get_all_rack(1); | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| sub get_all_rack | ||||
| { | ||||
|     my $class = shift; | ||||
|     my $hashref = shift; | ||||
|     my %rackhash = (); | ||||
|     my @racklist = (); | ||||
|  | ||||
|     my $racktab = xCAT::Table->new('rack'); | ||||
|     my @racks = $racktab->getAllAttribs(('rackname')); | ||||
|     foreach (@racks){ | ||||
|         if($_->{'rackname'}){ | ||||
|             if ($hashref){ | ||||
|                 $rackhash{$_->{'rackname'}} = 1; | ||||
|             }else { | ||||
|                 push @racklist, $_->{'rackname'}; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     | ||||
|     if ($hashref){ | ||||
|         return \%rackhash; | ||||
|     }else{ | ||||
|         return \@racklist; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
|  | ||||
| =head3 get_allnode_singleattrib_hash | ||||
|       Description : Get all records of a column from a table, then return a hash. | ||||
|                     The return hash's keys are the records of this attribute  | ||||
|   | ||||
| @@ -119,6 +119,9 @@ sub process_request { | ||||
|         $retref = xCAT::Utils->runxcmd({command=>["makedns"], node=>$nodelist}, $request_command, 0, 1); | ||||
|  | ||||
|         setrsp_progress("Update DHCP entries"); | ||||
|         $retref = xCAT::Utils->runxcmd({command=>["makedhcp"], node=>$nodelist, arg=>['-d']}, $request_command, 0, 1); | ||||
|         # we should restart dhcp so that the node's records in /var/lib/dhcpd/dhcpd.lease can be clean up and re-generate. | ||||
|         system("/etc/init.d/dhcpd restart"); | ||||
|         $retref = xCAT::Utils->runxcmd({command=>["makedhcp"], node=>$nodelist}, $request_command, 0, 1); | ||||
|  | ||||
|         setrsp_progress("Update known hosts"); | ||||
| @@ -167,9 +170,7 @@ sub process_request { | ||||
| sub setrsp_progress | ||||
| { | ||||
|     my $msg = shift; | ||||
|     my $rsp; | ||||
|     $rsp->{sinfo} = $msg; | ||||
|     $::CALLBACK->($rsp); | ||||
|     xCAT::MsgUtils->message('S', "$msg"); | ||||
| } | ||||
|  | ||||
| 1; | ||||
|   | ||||
| @@ -63,6 +63,8 @@ sub handled_commands { | ||||
|         nodediscoverstart => 'profilednodes', | ||||
|         nodediscoverstop => 'profilednodes', | ||||
|         nodediscoverls => 'profilednodes', | ||||
|         nodeaddunmged => 'profilednodes', | ||||
|         nodechmac => 'profilednodes', | ||||
|         findme => 'profilednodes', | ||||
|     }; | ||||
| } | ||||
| @@ -81,7 +83,7 @@ sub process_request { | ||||
|  | ||||
|     $request = shift; | ||||
|     $callback = shift; | ||||
|     $::CALLBACK = $callback; | ||||
|     #$::CALLBACK = $callback; | ||||
|     $request_command = shift; | ||||
|     $command = $request->{command}->[0]; | ||||
|     $args = $request->{arg}; | ||||
| @@ -94,7 +96,7 @@ sub process_request { | ||||
|     } | ||||
|  | ||||
|     # These commands should make sure no discover is running. | ||||
|     if (grep{ $_ eq $command} ("nodeimport", "nodepurge", "nodechprofile")){ | ||||
|     if (grep{ $_ eq $command} ("nodeimport", "nodepurge", "nodechprofile", "nodeaddunmged", "nodechmac")){ | ||||
|         my $discover_running = xCAT::ProfiledNodeUtils->is_discover_started(); | ||||
|         if ($discover_running){ | ||||
|             setrsp_errormsg("Can not run command $command as profiled nodes discover is running."); | ||||
| @@ -119,6 +121,10 @@ sub process_request { | ||||
|         findme(); | ||||
|     } elsif ($command eq "nodediscoverls"){ | ||||
|         nodediscoverls(); | ||||
|     } elsif ($command eq "nodeaddunmged"){ | ||||
|         nodeaddunmged(); | ||||
|     } elsif ($command eq "nodechmac"){ | ||||
|         nodechmac(); | ||||
|     } | ||||
|  | ||||
|     xCAT::ProfiledNodeUtils->release_lock($lockfh); | ||||
| @@ -184,7 +190,7 @@ sub parse_args{ | ||||
| sub nodeimport{ | ||||
|  | ||||
|     # Parse arges. | ||||
|     setrsp_infostr("Import profiled nodes through hostinfo file."); | ||||
|     xCAT::MsgUtils->message('S', "Import profiled nodes through hostinfo file."); | ||||
|     my $retstr = parse_args(); | ||||
|     if ($retstr){ | ||||
|         setrsp_errormsg($retstr); | ||||
| @@ -212,7 +218,7 @@ sub nodeimport{ | ||||
|     } | ||||
|  | ||||
|     # Get database records: all hostnames, all ips, all racks... | ||||
|     setrsp_infostr("Getting database records."); | ||||
|     xCAT::MsgUtils->message('S', "Getting database records."); | ||||
|     my $recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('nodelist', 'node'); | ||||
|     %allhostnames = %$recordsref; | ||||
|     $recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('ipmi', 'bmc'); | ||||
| @@ -236,13 +242,13 @@ sub nodeimport{ | ||||
|     %allips = (%allips, %allbmcips, %allinstallips); | ||||
|  | ||||
|     #TODO: can not use getallnode to get rack infos. | ||||
|     #$recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('rack', 'rackname'); | ||||
|     %allracks = (); | ||||
|     $recordsref = xCAT::ProfiledNodeUtils->get_all_rack(1); | ||||
|     %allracks = %$recordsref; | ||||
|     $recordsref =  xCAT::ProfiledNodeUtils->get_all_chassis(1); | ||||
|     %allchassis = %$recordsref; | ||||
|  | ||||
|     # Generate temporary hostnames for hosts entries in hostfile.  | ||||
|     setrsp_infostr("Generate temporary hostnames."); | ||||
|     xCAT::MsgUtils->message('S', "Generate temporary hostnames."); | ||||
|     my ($retcode_read, $retstr_read) = read_and_generate_hostnames($args_dict{'file'}); | ||||
|     if ($retcode_read != 0){ | ||||
|         setrsp_errormsg($retstr_read); | ||||
| @@ -250,7 +256,7 @@ sub nodeimport{ | ||||
|     } | ||||
|  | ||||
|     # Parse and validate the hostinfo string. The real hostnames will be generated here. | ||||
|     setrsp_infostr("Parsing hostinfo string and validate it."); | ||||
|     xCAT::MsgUtils->message('S', "Parsing hostinfo string and validate it."); | ||||
|     my ($hostinfo_dict_ref, $invalid_records_ref) = parse_hosts_string($retstr_read); | ||||
|     my %hostinfo_dict = %$hostinfo_dict_ref; | ||||
|     my @invalid_records = @$invalid_records_ref; | ||||
| @@ -264,13 +270,14 @@ sub nodeimport{ | ||||
|     } | ||||
|  | ||||
|     # Create the real hostinfo string in stanza file format. | ||||
|     setrsp_infostr("Generating new hostinfo string."); | ||||
|     xCAT::MsgUtils->message('S', "Generating new hostinfo string."); | ||||
|     my ($retcode_gen, $retstr_gen) = gen_new_hostinfo_string(\%hostinfo_dict); | ||||
|     unless ($retcode_gen){ | ||||
|         setrsp_errormsg($retstr_gen); | ||||
|         return; | ||||
|     } | ||||
|     # call mkdef to create hosts and then call nodemgmt for node management plugins. | ||||
|     setrsp_progress("Import nodes started."); | ||||
|     setrsp_progress("call mkdef to create nodes."); | ||||
|     my $retref = xCAT::Utils->runxcmd({command=>["mkdef"], stdin=>[$retstr_gen], arg=>['-z']}, $request_command, 0, 1); | ||||
|  | ||||
| @@ -278,6 +285,7 @@ sub nodeimport{ | ||||
|     setrsp_progress("call nodemgmt plugins."); | ||||
|     $retref = xCAT::Utils->runxcmd({command=>["kitnodeadd"], node=>\@nodelist}, $request_command, 0, 1); | ||||
|     $retref = xCAT::Utils->runxcmd({command=>["kitnodefinished"], node=>\@nodelist}, $request_command, 0, 1); | ||||
|     setrsp_progress("Import nodes success."); | ||||
|     setrsp_success(\@nodelist); | ||||
| } | ||||
|  | ||||
| @@ -293,13 +301,14 @@ sub nodeimport{ | ||||
| #------------------------------------------------------- | ||||
| sub nodepurge{ | ||||
|     my $nodes   = $request->{node}; | ||||
|     setrsp_infostr("Purging nodes."); | ||||
|     xCAT::MsgUtils->message('S', "Purging nodes."); | ||||
|     # For remove nodes, we should call 'nodemgmt' in front of 'noderm' | ||||
|     setrsp_infostr("Call kit node plugins."); | ||||
|     setrsp_progress("Call kit node plugins."); | ||||
|     my $retref = xCAT::Utils->runxcmd({command=>["kitnoderemove"], node=>$nodes}, $request_command, 0, 1); | ||||
|     $retref = xCAT::Utils->runxcmd({command=>["kitnodefinished"], node=>$nodes}, $request_command, 0, 1); | ||||
|     setrsp_infostr("Call noderm to remove nodes."); | ||||
|     setrsp_progress("Call noderm to remove nodes."); | ||||
|     $retref = xCAT::Utils->runxcmd({command=>["noderm"], node=>$nodes}, $request_command, 0, 1); | ||||
|     setrsp_progress("Purge nodes success."); | ||||
|     setrsp_success($nodes); | ||||
| } | ||||
|  | ||||
| @@ -335,7 +344,7 @@ sub nodechprofile{ | ||||
|     my $nodes   = $request->{node}; | ||||
|     my %updated_groups; | ||||
|  | ||||
|     setrsp_infostr("Update nodes' profile settings."); | ||||
|     xCAT::MsgUtils->message('S', "Update nodes' profile settings."); | ||||
|     # Parse arges. | ||||
|     my $retstr = parse_args(); | ||||
|     if ($retstr){ | ||||
| @@ -352,7 +361,7 @@ sub nodechprofile{ | ||||
|     } | ||||
|  | ||||
|     # Get current templates for all nodes. | ||||
|     setrsp_infostr("Read database to get groups for all nodes."); | ||||
|     setrsp_progress("Read database to get groups for all nodes."); | ||||
|     my %groupdict; | ||||
|     my $nodelstab = xCAT::Table->new('nodelist'); | ||||
|     my $nodeshashref = $nodelstab->getNodesAttribs($nodes, ['groups']); | ||||
| @@ -362,6 +371,9 @@ sub nodechprofile{ | ||||
|         my @groups; | ||||
|         my $attrshashref = $nodeshash{$_}[0]; | ||||
|         my %attrshash = %$attrshashref; | ||||
|         # Update node's status to defined | ||||
|         $updatenodeshash{$_}{'status'} = 'defined'; | ||||
|         # Update node's groups (profiles) info. | ||||
|         if ($attrshash{'groups'}){ | ||||
|             @groups = split(/,/, $attrshash{'groups'}); | ||||
|  | ||||
| @@ -381,18 +393,166 @@ sub nodechprofile{ | ||||
|     } | ||||
|      | ||||
|     #update DataBase. | ||||
|     setrsp_infostr("Update database records."); | ||||
|     setrsp_progress("Update database records."); | ||||
|     my $nodetab = xCAT::Table->new('nodelist',-create=>1); | ||||
|     $nodetab->setNodesAttribs(\%updatenodeshash); | ||||
|     $nodetab->close(); | ||||
|      | ||||
|     # call plugins | ||||
|     setrsp_infostr("Call nodemgmt plugins."); | ||||
|     setrsp_progress("Call nodemgmt plugins."); | ||||
|     my $retref = xCAT::Utils->runxcmd({command=>["kitnodeupdate"], node=>$nodes}, $request_command, 0, 1); | ||||
|     $retref = xCAT::Utils->runxcmd({command=>["kitnodefinished"], node=>$nodes}, $request_command, 0, 1); | ||||
|     setrsp_progress("Update node's profile success"); | ||||
|     setrsp_success($nodes); | ||||
| } | ||||
|  | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3 nodeaddunmged | ||||
|  | ||||
|     Description : Create a node with hostname and ip address specified. | ||||
|                   This node will belong to group "__Unmanaged". | ||||
|                   Host file /etc/hosts will be updated automatically. | ||||
|     Arguments   : N/A | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub nodeaddunmged | ||||
| { | ||||
|     xCAT::MsgUtils->message("Adding a unmanaged node."); | ||||
|     # Parse arges. | ||||
|     my $retstr = parse_args(); | ||||
|     if ($retstr){ | ||||
|         setrsp_errormsg($retstr); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     # Make sure the specified parameters are valid ones. | ||||
|     my @enabledparams = ('hostname', 'ip'); | ||||
|     foreach my $argname (keys %args_dict){ | ||||
|         if (! grep{ $_ eq $argname} @enabledparams){ | ||||
|             setrsp_errormsg("Illegal attribute $argname specified."); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     # Mandatory arguments. | ||||
|     foreach (('hostname','ip')){ | ||||
|         if(! exists($args_dict{$_})){ | ||||
|             setrsp_errormsg("Mandatory parameter $_ not specified."); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     # validate the IP address | ||||
|     my $recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('ipmi', 'bmc'); | ||||
|     %allbmcips = %$recordsref; | ||||
|     $recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('hosts', 'ip'); | ||||
|     %allinstallips = %$recordsref; | ||||
|     $recordsref = xCAT::NetworkUtils->get_all_nicips(1); | ||||
|     %allips = %$recordsref; | ||||
|  | ||||
|     %allips = (%allips, %allbmcips, %allinstallips); | ||||
|  | ||||
|     if (exists $allips{$args_dict{'ip'}}){ | ||||
|         setrsp_errormsg("Specified IP address $args_dict{'ip'} conflicts with IPs in database"); | ||||
|         return; | ||||
|     }elsif((xCAT::NetworkUtils->validate_ip($args_dict{'ip'}))[0][0] ){ | ||||
|         setrsp_errormsg("Specified IP address $args_dict{'ip'} is invalid"); | ||||
|         return; | ||||
|     }elsif(xCAT::NetworkUtils->isReservedIP($args_dict{'ip'})){ | ||||
|         setrsp_errormsg("Specified IP address $args_dict{'ip'} is invalid"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     # validate hostname. | ||||
|     $recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('nodelist', 'node'); | ||||
|     %allhostnames = %$recordsref; | ||||
|     if (exists $allhostnames{$args_dict{'hostname'}}){ | ||||
|         setrsp_errormsg("Specified hostname $args_dict{'hostname'} conflicts with records in database"); | ||||
|         return; | ||||
|     } | ||||
|     if (! xCAT::NetworkUtils->isValidHostname($args_dict{'hostname'})){ | ||||
|         setrsp_errormsg("Specified hostname: $args_dict{'hostname'} is invalid"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     # run nodeadd to create node records. | ||||
|     my $retref = xCAT::Utils->runxcmd({command=>["nodeadd"], arg=>[$args_dict{"hostname"}, "groups=__Unmanaged", "hosts.ip=$args_dict{'ip'}"]}, $request_command, 0, 1); | ||||
|     $retref = xCAT::Utils->runxcmd({command=>["makehosts"], node=>[$args_dict{"hostname"}]}, $request_command, 0, 1); | ||||
|     setrsp_infostr("Create unmanaged node success"); | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3 nodechmac | ||||
|  | ||||
|     Description : Change node's provisioning NIC's MAC address. | ||||
|                   And then call kits plugins for nodes. | ||||
|     Arguments   : N/A | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub nodechmac | ||||
| { | ||||
|     xCAT::MsgUtils->message("Replacing node's mac address."); | ||||
|     # Parse arges. | ||||
|     my $nodelist = $request->{node}; | ||||
|     my $hostname = $nodelist->[0]; | ||||
|     my $retstr = parse_args(); | ||||
|     if ($retstr){ | ||||
|         setrsp_errormsg($retstr); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     # Make sure the specified parameters are valid ones. | ||||
|     my @enabledparams = ('mac'); | ||||
|     foreach my $argname (keys %args_dict){ | ||||
|         if (! grep{ $_ eq $argname} @enabledparams){ | ||||
|             setrsp_errormsg("Illegal attribute $argname specified."); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     # Mandatory arguments. | ||||
|     foreach (('mac')){ | ||||
|         if(! exists($args_dict{$_})){ | ||||
|             setrsp_errormsg("Mandatory parameter $_ not specified."); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     # Validate MAC address | ||||
|     my $recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('mac', 'mac'); | ||||
|     %allmacs = %$recordsref; | ||||
|     foreach (keys %allmacs){ | ||||
|         my @hostentries = split(/\|/, $_); | ||||
|         foreach my $hostandmac ( @hostentries){ | ||||
|             my ($macstr, $machostname) = split("!", $hostandmac); | ||||
|             $allmacs{$macstr} = 0; | ||||
|         } | ||||
|     } | ||||
|     if (exists $allmacs{$args_dict{"mac"}}){ | ||||
|         setrsp_errormsg("Specified MAC address $args_dict{'mac'} conflicts with MACs in database"); | ||||
|         return; | ||||
|     } elsif(! xCAT::NetworkUtils->isValidMAC($args_dict{'mac'})){ | ||||
|         setrsp_errormsg("Specified MAC address $args_dict{'mac'} is invalid"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     # Update database records. | ||||
|     setrsp_progress("Updating database records"); | ||||
|     my $mactab = xCAT::Table->new('mac',-create=>1); | ||||
|     $mactab->setNodeAttribs($hostname, {mac=>$args_dict{'mac'}}); | ||||
|     $mactab->close(); | ||||
|  | ||||
|     # Call Plugins. | ||||
|     setrsp_progress("Calling kit plugins"); | ||||
|     my $retref = xCAT::Utils->runxcmd({command=>["kitnodeupdate"], node=>[$hostname]}, $request_command, 0, 1); | ||||
|     $retref = xCAT::Utils->runxcmd({command=>["kitnodefinished"], node=>[$hostname]}, $request_command, 0, 1); | ||||
|     setrsp_progress("Change node's mac success"); | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3 nodediscoverstart  | ||||
| @@ -413,14 +573,14 @@ sub nodechprofile{ | ||||
| #------------------------------------------------------- | ||||
| sub nodediscoverstart{ | ||||
|     # Parse arges. | ||||
|     setrsp_infostr("Profiled nodes discovery started."); | ||||
|     xCAT::MsgUtils->message("Profiled nodes discovery started."); | ||||
|     my $retstr = parse_args(); | ||||
|     if ($retstr){ | ||||
|         setrsp_errormsg($retstr); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     my @enabledparams = ('networkprofile', 'hardwareprofile', 'imageprofile', 'hostnameformat', 'rank', 'rack', 'chassis', 'height', 'u'); | ||||
|     my @enabledparams = ('networkprofile', 'hardwareprofile', 'imageprofile', 'hostnameformat', 'rank', 'rack', 'chassis', 'height', 'unit'); | ||||
|     foreach my $argname (keys %args_dict){ | ||||
|         if (! grep{ $_ eq $argname} @enabledparams){ | ||||
|             setrsp_errormsg("Illegal attribute $argname specified."); | ||||
| @@ -435,6 +595,58 @@ sub nodediscoverstart{ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     my $recordsref = xCAT::ProfiledNodeUtils->get_all_rack(1); | ||||
|     %allracks = %$recordsref; | ||||
|     $recordsref =  xCAT::ProfiledNodeUtils->get_all_chassis(1); | ||||
|     %allchassis = %$recordsref; | ||||
|     # check rack | ||||
|     if (exists $args_dict{'rack'}){ | ||||
|         if (! exists $allracks{$args_dict{'rack'}}){ | ||||
|             setrsp_errormsg("Specified rack $args_dict{'rack'} not defined"); | ||||
|             return; | ||||
|         } | ||||
|         # rack must be specified with chassis or unit + height. | ||||
|         if (exists $args_dict{'chassis'}){ | ||||
|         } else{ | ||||
|             # We set default value for height and u if rack specified | ||||
|             if(! exists $args_dict{'height'}){$args_dict{'height'} = 1} | ||||
|             if(! exists $args_dict{'unit'}){$args_dict{'unit'} = 1} | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # chassis jdugement. | ||||
|     if (exists $args_dict{'chassis'}){ | ||||
|         if (! exists  $args_dict{'rack'}){ | ||||
|             setrsp_errormsg("Argument chassis must be used together with rack"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (! exists $allchassis{$args_dict{'chassis'}}){ | ||||
|             setrsp_errormsg("Specified chassis $args_dict{'chassis'} not defined"); | ||||
|             return; | ||||
|         } | ||||
|         if (exists $args_dict{'unit'} or exists $args_dict{'height'}){ | ||||
|             setrsp_errormsg("Argument chassis can not be specified together with unit or height"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     | ||||
|     # height and u must be valid numbers. | ||||
|     if (exists $args_dict{'unit'}){ | ||||
|         # Not a valid number. | ||||
|         if (!($args_dict{'unit'} =~ /^\d+$/)){ | ||||
|             setrsp_errormsg("Specified unit $args_dict{'u'} is a invalid number"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     if (exists $args_dict{'height'}){ | ||||
|         # Not a valid number. | ||||
|         if (!($args_dict{'height'} =~ /^\d+$/)){ | ||||
|             setrsp_errormsg("Specified height $args_dict{'height'} is a invalid number"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # Read DB to confirm the discover is not started yet.  | ||||
|     my @sitevalues = xCAT::TableUtils->get_site_attribute("__PCMDiscover"); | ||||
|     if ($sitevalues[0]){ | ||||
| @@ -453,7 +665,7 @@ sub nodediscoverstart{ | ||||
|     my $sitetab = xCAT::Table->new('site',-create=>1); | ||||
|     $sitetab->setAttribs({"key" => "__PCMDiscover"}, {"value" => "$valuestr"}); | ||||
|     $sitetab->close(); | ||||
|  | ||||
|     setrsp_infostr("Profiled node's discover started"); | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| @@ -469,6 +681,7 @@ sub nodediscoverstart{ | ||||
| #------------------------------------------------------ | ||||
| sub nodediscoverstop{ | ||||
|     # Read DB to confirm the discover is started.  | ||||
|     xCAT::MsgUtils->message("Stopping profiled node's discover."); | ||||
|     my @sitevalues = xCAT::TableUtils->get_site_attribute("__PCMDiscover"); | ||||
|     if (! $sitevalues[0]){ | ||||
|         setrsp_errormsg("Profiled nodes discovery not started yet."); | ||||
| @@ -489,6 +702,7 @@ sub nodediscoverstop{ | ||||
|         # There are some nodes discvoered. | ||||
|         my $retref = xCAT::Utils->runxcmd({command=>["rmdef"], arg=>["-t", "group", "-o", "__PCMDiscover"]}, $request_command, 0, 1); | ||||
|     } | ||||
|     setrsp_infostr("Profiled node's discover stopped"); | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| @@ -523,8 +737,17 @@ sub nodediscoverls{ | ||||
|             next; | ||||
|         } | ||||
|         $rspentry->{info}->[$i]->{"node"} = $_; | ||||
|         #TODO: get provisioning mac. | ||||
|         $rspentry->{info}->[$i]->{"mac"} = $macsref->{$_}->[0]->{"mac"}; | ||||
|         # Only get the MAC address of provisioning NIC. | ||||
|         my @hostentries = split(/\|/, $macsref->{$_}->[0]->{"mac"}); | ||||
|         foreach my $hostandmac ( @hostentries){ | ||||
|             if (! $hostandmac){ | ||||
|                 next; | ||||
|             } | ||||
|             if(index($hostandmac, "!")  == -1){ | ||||
|                 $rspentry->{info}->[$i]->{"mac"} = $hostandmac; | ||||
|                 last; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($statusref->{$_}->[0]){ | ||||
|             $rspentry->{info}->[$i]->{"status"} = $statusref->{$_}->[0]; | ||||
| @@ -592,43 +815,11 @@ sub findme{ | ||||
|     # Merge all BMC IPs and install IPs into allips. | ||||
|     %allips = (%allips, %allbmcips, %allinstallips); | ||||
|  | ||||
|     #$recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('rack', 'rackname'); | ||||
|     #%allracks = %$recordsref; | ||||
|     %allracks = (); | ||||
|     $recordsref = xCAT::ProfiledNodeUtils->get_all_rack(1); | ||||
|     %allracks = %$recordsref; | ||||
|     $recordsref =  xCAT::ProfiledNodeUtils->get_all_chassis(1); | ||||
|     %allchassis = %$recordsref; | ||||
|  | ||||
|     my @enabledparams = ('networkprofile', 'hardwareprofile', 'imageprofile', 'hostnameformat', 'rack', 'chassis', 'u', 'height', 'rank'); | ||||
|     foreach my $argname (keys %args_dict){ | ||||
|         if (! grep{ $_ eq $argname} @enabledparams){ | ||||
|             setrsp_errormsg("Illegal attribute $argname specified."); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|     # mandatory arguments. | ||||
|     foreach my $key ('networkprofile', 'imageprofile', 'hostnameformat'){ | ||||
|         if (! exists $args_dict{$key}){ | ||||
|             setrsp_errormsg("argument $key must be specified"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # set default value for rack, startunit and height if not specified. | ||||
|     if (exists $args_dict{'rack'}){ | ||||
|         if (! exists $allracks{$args_dict{'rack'}}){ | ||||
|             setrsp_errormsg("Specified rack $args_dict{'rack'} not defined"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # chassis jdugement. | ||||
|     if (exists $args_dict{'chassis'}){ | ||||
|         if (! exists $allchassis{$args_dict{'chassis'}}){ | ||||
|             setrsp_errormsg("Specified chassis $args_dict{'chassis'} not defined"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # Get discovered client IP and MAC | ||||
|     my $ip = $request->{'_xcat_clientip'}; | ||||
|     xCAT::MsgUtils->message('S', "Profield nodes discover: _xcat_clientip is $ip.\n"); | ||||
| @@ -655,14 +846,25 @@ sub findme{ | ||||
|     # it will detect this and arrange a real hostname for it. | ||||
|     my $raw_hostinfo_str = "TMPHOSTS9999:\n  mac=$mac\n"; | ||||
|     # Append rack, chassis, unit, height into host info string. | ||||
|     foreach my $key ('rack', 'chassis', 'u', 'height'){ | ||||
|     foreach my $key ('rack', 'chassis', 'unit', 'height'){ | ||||
|         if(exists($args_dict{$key})){ | ||||
|             $raw_hostinfo_str .= "  $key=$args_dict{$key}\n"; | ||||
|         } | ||||
|     } | ||||
|     if (exists $args_dict{'u'} and exists $args_dict{'height'}){ | ||||
|     if (exists $args_dict{'unit'} and exists $args_dict{'height'}){ | ||||
|         # increase start unit automatically. | ||||
|         $args_dict{'u'} = $args_dict{'u'} + $args_dict{'height'}; | ||||
|         $args_dict{'unit'} = $args_dict{'unit'} + $args_dict{'height'}; | ||||
|         # save discover args into table site. | ||||
|         my $valuestr = ""; | ||||
|         foreach (keys %args_dict){ | ||||
|             if($args_dict{$_}){ | ||||
|                 $valuestr .= "$_:$args_dict{$_},"; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         my $sitetab = xCAT::Table->new('site',-create=>1); | ||||
|         $sitetab->setAttribs({"key" => "__PCMDiscover"}, {"value" => "$valuestr"}); | ||||
|         $sitetab->close(); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -679,8 +881,6 @@ sub findme{ | ||||
|     # call mkdef to create hosts and then call nodemgmt for node management plugins. | ||||
|     xCAT::MsgUtils->message('S', "Call mkdef to create nodes.\n"); | ||||
|     my $retref = xCAT::Utils->runxcmd({command=>["mkdef"], stdin=>[$retstr_gen], arg=>['-z']}, $request_command, 0, 1); | ||||
|     # increase unit automatically. | ||||
|     $args_dict{'u'} = $args_dict{'u'} + $args_dict{'height'}; | ||||
|  | ||||
|     my @nodelist = keys %hostinfo_dict; | ||||
|     xCAT::MsgUtils->message('S', "Call nodemgmt plugins.\n"); | ||||
| @@ -1021,22 +1221,22 @@ sub validate_node_entry{ | ||||
|             } | ||||
|             # rack must be specified with chassis or unit + height. | ||||
|             if (exists $node_entry{"chassis"}){ | ||||
|             } elsif (exists $node_entry{"height"} and exists $node_entry{"u"}){ | ||||
|             } elsif (exists $node_entry{"height"} and exists $node_entry{"unit"}){ | ||||
|             } else { | ||||
|                 return "Rack must be specified together with chassis or height + u "; | ||||
|                 return "Rack must be specified together with chassis or height + unit "; | ||||
|             } | ||||
|         }elsif ($_ eq "chassis"){ | ||||
|             if (not exists $allchassis{$node_entry{$_}}){ | ||||
|                 return "Specified chassis $node_entry{$_} not defined"; | ||||
|             } | ||||
|             # Chassis must not be specified with unit and height. | ||||
|             if (exists $node_entry{"height"} and exists $node_entry{"u"}){ | ||||
|                 return "Chassis should not be specified together with height + u"; | ||||
|             if (exists $node_entry{"height"} or exists $node_entry{"unit"}){ | ||||
|                 return "Chassis should not be specified together with height or unit"; | ||||
|             } | ||||
|         }elsif ($_ eq "u"){ | ||||
|         }elsif ($_ eq "unit"){ | ||||
|             # Not a valid number. | ||||
|             if (!($node_entry{$_} =~ /^\d+$/)){ | ||||
|                 return "Specified u $node_entry{$_} is a invalid number"; | ||||
|                 return "Specified unit $node_entry{$_} is a invalid number"; | ||||
|             } | ||||
|         }elsif ($_ eq "height"){ | ||||
|             # Not a valid number. | ||||
| @@ -1081,6 +1281,8 @@ sub setrsp_invalidrecords | ||||
|         print $fh "nodename $erroritem[0], error: $erroritem[1]\n"; | ||||
|     } | ||||
|     close $fh; | ||||
|     #make it readable for http. | ||||
|     system("chmod +r $filename"); | ||||
|     # Tells the URL of the details file. | ||||
|     xCAT::MsgUtils->message('S', "Detailed response info placed in file: http://$master/$filename\n"); | ||||
|     $rsp->{data}->{details} = "http://$master/$filename"; | ||||
| @@ -1170,6 +1372,8 @@ sub setrsp_success | ||||
|         print $fh "success: $_\n"; | ||||
|     } | ||||
|     close $fh; | ||||
|     #make it readable for http. | ||||
|     system("chmod +r $filename"); | ||||
|     # Tells the URL of the details file. | ||||
|     xCAT::MsgUtils->message('S', "Detailed response info placed in file: http://$master/$filename\n"); | ||||
|     $rsp->{data}->{details} = "http://$master/$filename"; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user