diff --git a/perl-xCAT/xCAT/ProfiledNodeUtils.pm b/perl-xCAT/xCAT/ProfiledNodeUtils.pm index 750ef892f..766f7a63e 100644 --- a/perl-xCAT/xCAT/ProfiledNodeUtils.pm +++ b/perl-xCAT/xCAT/ProfiledNodeUtils.pm @@ -1312,3 +1312,153 @@ sub get_all_vmhosts # Return the ref accordingly return \%vmhostshash; } + +#------------------------------------------------------------------------------- + +=head3 get_netboot_attr + Description : Get netboot attribute for node + Arguments : $imageprofile - image profile name, mandatory. e.g. "__ImageProfile_rhels7.0-x86_64-stateful-mgmtnode" + $hardwareprofile - harware profile name, optional. e.g. "__HardwareProfile_IBM_System_x_M4" + Returns : (returncode, netboot) + returncode=0 - can not get netboot value,netboot is the error message + returncode=1 - can get netboot value,netboot is the right value +=cut + +#------------------------------------------------------------------------------- +sub get_netboot_attr{ + my $class = shift; + my $imageprofile = shift; + my $hardwareprofile = shift; + my $netboot; + + my @nodegrps = xCAT::TableUtils->list_all_node_groups(); + unless(grep{ $_ eq $imageprofile} @nodegrps) + { + return 0, "Image profile not defined in DB." + } + $imageprofile =~ s/^__ImageProfile_//; + + if ($hardwareprofile){ + unless(grep{ $_ eq $hardwareprofile} @nodegrps) + { + return 0, "Hardware profile not defined in DB." + } + $hardwareprofile =~ s/^__HardwareProfile_//; + } + else + { + $hardwareprofile = '*'; + } + + # Get os name, os major version, osarch + my $osimage_tab = xCAT::Table->new('osimage'); + my $osimage_tab_entry = $osimage_tab->getAttribs({'imagename'=> $imageprofile},('osdistroname')); + my $osdistroname = $osimage_tab_entry->{'osdistroname'}; + $osimage_tab->close(); + + my $osdistro_tab = xCAT::Table->new('osdistro'); + my $osdistro_tab_entry = $osdistro_tab->getAttribs({'osdistroname'=> $osdistroname},('basename', 'majorversion', 'arch')); + my $os_name = $osdistro_tab_entry->{'basename'}; + my $os_major_version = $osdistro_tab_entry->{'majorversion'}; + my $os_arch = $osdistro_tab_entry->{'arch'}; + $osdistro_tab->close; + + # Treate os name rhel,centos,rhelhpc same as rhels + if ($os_name eq 'centos' || $os_name eq 'rhelhpc' || $os_name eq 'rhel') + { + $os_name = 'rhels'; + } + # Treate arch ppc64el same as ppc64le,x86 same as x86_64 + if ($os_arch eq 'ppc64el') + { + $os_arch = 'ppc64le'; + }elsif ($os_arch eq 'x86') + { + $os_arch = 'x86_64'; + } + +# Rule for netboot attribute.If update the rule,just update %netboot_dict and @condition_array +# It's sequence sensitive: os arch -> os name -> os major version -> hardware profile +# Priority | Arch | OS Name | OS Major Version | Hardware Profile | Noderes.netboot | +# 1 | x86_64/x86 | * | * | * | xnba | +# 2 | ppc64 | rhels | 7 | * | grub2 | +# 3 | | * | * | * | yaboot | +# 4 | ppc64le/el | * | * | IBM_PowerNV | petiboot | +# 5 | | * | * | * | grub2 | +# arch osname version hardware netboot + my %netboot_dict = ( 'x86_64' => 'xnba', + 'ppc64' => { + 'rhels' => { + '7' => 'grub2', + '*' => 'yaboot', + }, + '*' => 'yaboot', + }, + 'ppc64le' => { + '*' => { + '*' => { + 'IBM_PowerNV' => 'petiboot', + '*' => 'grub2', + }, + }, + }, + ); + my $condition_array_ref = [$os_arch, $os_name, $os_major_version, $hardwareprofile]; + $netboot = cal_netboot(\%netboot_dict, $condition_array_ref); + if($netboot eq '0') + { + return 0, "Can not get the netboot attribute"; + } + else + { + return 1, $netboot; + } +} +#------------------------------------------------------------------------------- + +=head3 cal_netboot + Description : Calculate netboot attribute by conditions recursively, internal use. + Arguments : $netboot_dict_ref + $condition_array_ref + Returns : netboot + returncode=0 - can not get netboot value +=cut + +#------------------------------------------------------------------------------- +sub cal_netboot{ + my $netboot_dict_ref = shift; + my $condition_array_ref = shift; + my $condition_array_len = scalar @$condition_array_ref; + + if( $condition_array_len == 0 ){ + return 0; + } + + my $condition = shift $condition_array_ref; + if( (exists($netboot_dict_ref->{$condition})) || (exists($netboot_dict_ref->{'*'})) ) + { + if(!exists($netboot_dict_ref->{$condition})) + { + $condition = '*'; + } + if(ref($netboot_dict_ref->{$condition}) eq 'HASH') + { + if($condition_array_len > 1) + { + return cal_netboot($netboot_dict_ref->{$condition}, $condition_array_ref); + } + else + { + return 0; + } + } + else + { + return $netboot_dict_ref->{$condition}; + } + } + else + { + return 0; + } +} diff --git a/xCAT-server/lib/xcat/plugins/profilednodes.pm b/xCAT-server/lib/xcat/plugins/profilednodes.pm index 33544a373..d674c4c4a 100644 --- a/xCAT-server/lib/xcat/plugins/profilednodes.pm +++ b/xCAT-server/lib/xcat/plugins/profilednodes.pm @@ -45,6 +45,7 @@ my %all_switchports; my %allvmhosts; my @switch_records; +my $netboot; # The array of all chassis which is special CMM my %allcmmchassis; @@ -381,6 +382,13 @@ Usage: setrsp_errormsg($errmsg); return; } + # Get the netboot attribute for node + my ($retcode, $retval) = xCAT::ProfiledNodeUtils->get_netboot_attr($imageprofile, $hardwareprofile); + if (not $retcode) { + setrsp_errormsg($retval); + return; + } + $netboot = $retval; # Get database records: all hostnames, all ips, all racks... xCAT::MsgUtils->message('S', "Getting database records."); @@ -767,6 +775,7 @@ Usage: my $nodelstab = xCAT::Table->new('nodelist'); my $nodeshashref = $nodelstab->getNodesAttribs($nodes, ['groups']); my %updatenodeshash; + my %updatenodereshash; my %nodeoldprofiles = (); foreach (@$nodes){ @@ -870,18 +879,27 @@ Usage: setrsp_infostr("Warning: no profile changes detect."); return; } - + # Get the netboot attribute for node + my ($retcode, $retval) = xCAT::ProfiledNodeUtils->get_netboot_attr($imageprofile, $hardwareprofile); + if (not $retcode) { + setrsp_errormsg($retval); + return; + } + my $new_netboot = $retval; # Update nodes' attributes foreach (@$nodes) { $updatenodeshash{$_}{'groups'} .= $profile_groups; - } + $updatenodereshash{$_}{'netboot'} = $new_netboot; + } #update DataBase. setrsp_progress("Updating database records..."); my $nodetab = xCAT::Table->new('nodelist',-create=>1); $nodetab->setNodesAttribs(\%updatenodeshash); $nodetab->close(); - + my $noderestab = xCAT::Table->new('noderes',-create=>1); + $noderestab->setNodesAttribs(\%updatenodereshash); + $noderestab->close(); #update node's status: if($profile_status eq "defined"){ xCAT::Utils->runxcmd({command=>["updatenodestat"], node=>$nodes, arg=>['defined']}, $request_command, -1, 2); @@ -1778,6 +1796,16 @@ sub findme{ } } } + my $imageprofile = $args_dict{'imageprofile'}; + my $networkprofile = $args_dict{'networkprofile'}; + my $hardwareprofile = $args_dict{'hardwareprofile'}; + # Get the netboot attribute for node + my ($retcode, $retval) = xCAT::ProfiledNodeUtils->get_netboot_attr($imageprofile, $hardwareprofile); + if (not $retcode) { + setrsp_errormsg($retval); + return; + } + $netboot = $retval; # Get database records: all hostnames, all ips, all racks... # To improve performance, we should initalize a daemon later?? @@ -2108,11 +2136,8 @@ sub gen_new_hostinfo_dict{ $hostinfo_dict{$item}{"mgt"} = "fsp"; } - # Generate VM host nodes' attribute - # Update netboot attribute if this is powerKVM node - if (exists $hostinfo_dict{$item}{"vmhost"}){ - $hostinfo_dict{$item}{"netboot"} = 'grub2'; - } + # Set netboot attribute for node + $hostinfo_dict{$item}{"netboot"} = $netboot; # get the chain attribute from hardwareprofile and insert it to node. my $chaintab = xCAT::Table->new('chain');