From de4ccd729e2973219fb7cacfc8710c7c9877fb7b Mon Sep 17 00:00:00 2001 From: Lei Ai Date: Tue, 12 Aug 2014 17:18:31 +0800 Subject: [PATCH] Support runimages associating with hardwareprofiles while replace nodes (nodechmac) --- perl-xCAT/xCAT/ProfiledNodeUtils.pm | 78 ++++++- xCAT-server/lib/xcat/plugins/profilednodes.pm | 206 ++++++++++-------- 2 files changed, 194 insertions(+), 90 deletions(-) diff --git a/perl-xCAT/xCAT/ProfiledNodeUtils.pm b/perl-xCAT/xCAT/ProfiledNodeUtils.pm index c54d326fe..62c1b5081 100644 --- a/perl-xCAT/xCAT/ProfiledNodeUtils.pm +++ b/perl-xCAT/xCAT/ProfiledNodeUtils.pm @@ -690,6 +690,7 @@ sub get_nodes_profiles { my $class = shift; my $nodelistref = shift; + my $groupnamemode = shift; my %profile_dict; my $nodelisttab = xCAT::Table->new('nodelist'); @@ -709,8 +710,12 @@ sub get_nodes_profiles if ( $idx == 2 ){ # The group string will like @NetworkProfile_ # So, index should +3, 2 for '__', 1 for _. - my $append_index = length($profile) + 3; - $profile_dict{$_}{$profile} = substr $group, $append_index; + if ($groupnamemode) { + $profile_dict{$_}{$profile} = $group; + } else{ + my $append_index = length($profile) + 3; + $profile_dict{$_}{$profile} = substr $group, $append_index; + } last; } } @@ -739,7 +744,7 @@ sub get_imageprofile_prov_method my $nodetypestab = xCAT::Table->new('nodetype'); my $entry = ($nodetypestab->getAllAttribsWhere("node = '$imgprofilename'", 'ALL' ))[0]; - my $osimgname = $entry->{'provmethod'}; + return $entry->{'provmethod'}; #my $osimgtab = xCAT::Table->new('osimage'); #my $osimgentry = ($osimgtab->getAllAttribsWhere("imagename = '$osimgname'", 'ALL' ))[0]; @@ -1148,3 +1153,70 @@ sub check_nicips{ return (0, \%nics_hash, ""); } +#------------------------------------------------------------------------------- +=head3 gen_chain_for_profiles + Description: Generate a chain string based on Network/Hardware/Image profiles. + Arguments: $profiles_hash: The reference for profiles hash. + For example: + $profiles_hash = { 'HardwareProfile' => 'IBM_NeXtScale_M4', + 'ImageProfile' => 'rhels6.5-x86_64-stateful-compute', + 'NetworkProfile' => 'default_network_profile', + } + $hw_reconfig: the flag shows whether we need re-configure all hardware + relative settings or not: like runcmds, runimg...etc + Returns: ($retcode, $chain) + $retcode = 1. Generate chain failed, $chain stands for error message. + $retcode = 0. Generate chain OK. $chain stands for the chain string. + +=cut +#------------------------------------------------------------------------------- +sub gen_chain_for_profiles{ + my $class = shift; + my $profiles_hashref = shift; + my $hw_reconfig = shift; + my $final_chain = ""; + if (! $profiles_hashref){ + return (1, "Missing parameter for gen_chain_for_profiles."); + } + # A node must have at least imageprofile and network profile. + unless (defined $profiles_hashref->{'ImageProfile'}){ + return (1, "No imageprofile specified in profiles hash."); + } + unless (defined $profiles_hashref->{'NetworkProfile'}){ + return (1, "No networkprofile specified in profiles hash."); + } + my $hwprofile = $profiles_hashref->{'HardwareProfile'}; + my $imgprofile = $profiles_hashref->{'ImageProfile'}; + my $netprofile = $profiles_hashref->{'NetworkProfile'}; + + # Get node's provisioning method + my $provmethod = xCAT::ProfiledNodeUtils->get_imageprofile_prov_method($imgprofile); + unless ($provmethod ){ + return (1, "Can not get provisioning method for image profile $imgprofile"); + } + my $netprofileattr = xCAT::ProfiledNodeUtils->get_nodes_nic_attrs([$netprofile])->{$netprofile}; + unless ($netprofileattr){ + return (1, "Can not get attributes for network profile $netprofile"); + } + + $final_chain = 'osimage='.$provmethod.":--noupdateinitrd"; + # get the chain attribute from hardwareprofile and insert it to node. + if (defined $hwprofile and $hwprofile and $hw_reconfig){ + my $chaintab = xCAT::Table->new('chain'); + my $chain = $chaintab->getNodeAttribs($hwprofile, ['chain']); + if (exists $chain->{'chain'}) { + my $hw_chain = $chain->{'chain'}; + $final_chain = $hw_chain.',osimage='.$provmethod.":--noupdateinitrd"; + } + } + #run bmcsetups. + if ((exists $netprofileattr->{"bmc"}) and $hw_reconfig){ + if (index($final_chain, "runcmd=bmcsetup") == -1){ + $final_chain = 'runcmd=bmcsetup,'.$final_chain.':reboot4deploy'; + } + else{ + $final_chain = $final_chain.':reboot4deploy'; + } + } + return (0, $final_chain); +} diff --git a/xCAT-server/lib/xcat/plugins/profilednodes.pm b/xCAT-server/lib/xcat/plugins/profilednodes.pm index 109ba66d5..c7e5a65ef 100644 --- a/xCAT-server/lib/xcat/plugins/profilednodes.pm +++ b/xCAT-server/lib/xcat/plugins/profilednodes.pm @@ -783,19 +783,9 @@ Usage: my $retref; my $retstrref; - # Call update plugins first. - if(exists $args_dict{'hardwareprofile'} || exists $args_dict{'imageprofile'}){ - setrsp_progress("Configuring nodes..."); - $retref = ""; - $retref = xCAT::Utils->runxcmd({command=>["kitnodeupdate"], node=>$nodes, sequential=>[1]}, $request_command, 0, 2); - $retstrref = parse_runxcmd_ret($retref); - if ($::RUNCMD_RC != 0){ - setrsp_progress("Warning: failed to call kit commands."); - } - } # If network profile specified. Need re-generate IPs for all nodess again. - # As new design, ignore BMC/FSP NIC while reinstall nodes + # As new design, ignore BMC/FSP NIC while reinstall nodes if(exists $args_dict{'networkprofile'}){ my $newNetProfileName = $args_dict{'networkprofile'}; my $oldNetProfileName = $nodeoldprofiles{'networkprofile'}; @@ -824,7 +814,73 @@ Usage: setrsp_progress("Warning: failed to generate IPs for nodes."); } } - + + # Update node's chain table if we need to re-provisioning OS... + # We need to re-provision OS if: + # hardware profile changed or + # image profile changed or + # network profile changed. + if ((exists $args_dict{'networkprofile'}) or + (exists $args_dict{'hardwareprofile'}) or + (exists $args_dict{'imageprofile'})){ + + my $nodetypetab = xCAT::Table->new('nodetype'); + my $firstnode = $nodes->[0]; + my $profiles = xCAT::ProfiledNodeUtils->get_nodes_profiles([$firstnode], 1); + unless ($profiles){ + setrsp_errormsg("Can not get node profiles."); + return; + } + + # If we have hardware changes, reconfigure everything including BMC. + my $chainret = 0; + my $chainstr = ""; + if(exists $args_dict{'hardwareprofile'}){ + ($chainret, $chainstr) = xCAT::ProfiledNodeUtils->gen_chain_for_profiles($profiles->{$firstnode}, 1); + } else { + ($chainret, $chainstr) = xCAT::ProfiledNodeUtils->gen_chain_for_profiles($profiles->{$firstnode}, 0); + } + if ($chainret != 0){ + setrsp_errormsg("Failed to generate chain string for nodes."); + return; + } + + # DB update: chain table. + my %chainAttr = {}; + foreach my $node (@$nodes){ + $chainAttr{$node}{'chain'} = $chainstr; + } + my $chaintab = xCAT::Table->new('chain', -create=>1); + $chaintab->setNodesAttribs(\%chainAttr); + $chaintab->close(); + + + # Run node plugins to refresh node relateive configurations. + $retref = {}; + setrsp_progress("Updating DNS entries"); + $retref = xCAT::Utils->runxcmd({command=>["makedns"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2); + my $retstrref = parse_runxcmd_ret($retref); + if ($::RUNCMD_RC != 0){ + setrsp_progress("Warning: failed to call kit commands."); + } + + $retref = {}; + setrsp_progress("Updating hosts entries"); + $retref = xCAT::Utils->runxcmd({command=>["makehosts"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2); + $retref = {}; + $retstrref = parse_runxcmd_ret($retref); + if ($::RUNCMD_RC != 0){ + setrsp_progress("Warning: failed to call kit commands."); + } + + setrsp_progress("Re-creating nodes..."); + $retref = xCAT::Utils->runxcmd({command=>["kitnodeadd"], node=>$nodes, macflag=>[1]}, $request_command, 0, 2); + $retstrref = parse_runxcmd_ret($retref); + if ($::RUNCMD_RC != 0){ + setrsp_progress("Warning: failed to call kit commands."); + } + + } setrsp_progress("Updated the image/network/hardware profiles used by nodes."); setrsp_success($nodes); } @@ -1009,65 +1065,6 @@ Usage: $ppctab->close(); } - #9. If provisioning NIC ip or BMC ip changed for nodes, update chain table - # If FSP ip changed for nodes, push the new ip to fsp and establish hardware connection - my @kitcommands = (); - if ( $provision_flag or $bmc_flag) { - #Get node's provmethod. - my $nodetypetab = xCAT::Table->new('nodetype'); - my $firstnode = $nodes->[0]; - my $records = $nodetypetab->getNodeAttribs($firstnode, ['node', 'provmethod']); - my $imgname = $records->{provmethod}; - - my $chainstr = "osimage=$imgname"; - if ( $bmc_flag ) { - $chainstr = "runcmd=bmcsetup,osimage=$imgname:reboot4deploy"; - } - - # Update chain table - my %chainAttr = {}; - foreach my $node (@$nodes){ - $chainAttr{$node}{'chain'} = $chainstr; - } - my $chaintab = xCAT::Table->new('chain', -create=>1); - $chaintab->setNodesAttribs(\%chainAttr); - $chaintab->close(); - - # Remove all nodes information - push(@kitcommands, "removenodes"); - # Add all nodes information back - push(@kitcommands, "kitnodeadd"); - - } elsif ( $fsp_flag ) { - # Remove all nodes information - push(@kitcommands, "removenodes"); - # Add all nodes information back - push(@kitcommands, "kitnodeadd"); - } else { - push(@kitcommands, "kitnoderefresh"); - } - - #10. Call plugins. - foreach my $command (@kitcommands) { - my $retref; - if ($command eq 'removenodes'){ - setrsp_progress("Updating DNS entries"); - $retref = xCAT::Utils->runxcmd({command=>["makedns"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2); - - setrsp_progress("Updating hosts entries"); - $retref = ""; - $retref = xCAT::Utils->runxcmd({command=>["makehosts"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2); - next; - } - $retref = ""; - $retref = xCAT::Utils->runxcmd({command=>[$command], node=>$nodes, sequential=>[1]}, $request_command, 0, 2); - my $retstrref = parse_runxcmd_ret($retref); - if ($::RUNCMD_RC != 0){ - setrsp_progress("Warning: failed to call kit commands."); - last; - } - } - setrsp_progress("Re-generated node's IPs for specified nics."); setrsp_success($nodes); } @@ -1208,20 +1205,59 @@ Usage: return; } + # re-create the chain record as updating mac may means for replacing a new brand hardware... + # Call Plugins. + my $profiles = xCAT::ProfiledNodeUtils->get_nodes_profiles([$hostname], 1); + unless ($profiles){ + setrsp_errormsg("Can not get node profiles."); + return; + } + + (my $chainret, my $chainstr) = xCAT::ProfiledNodeUtils->gen_chain_for_profiles($profiles->{$hostname}, 1); + if ($chainret != 0){ + setrsp_errormsg("Failed to generate chain string for nodes."); + return; + } + # Update database records. setrsp_progress("Updating database..."); + # MAC table my $mactab = xCAT::Table->new('mac',-create=>1); $mactab->setNodeAttribs($hostname, {mac=>$args_dict{'mac'}}); $mactab->close(); - # Call Plugins. + # DB update: chain table. + my $chaintab = xCAT::Table->new('chain', -create=>1); + $mactab->setNodeAttribs($hostname, {chain=>$chainstr}); + $chaintab->close(); + + + # Run node plugins to refresh node relateive configurations. setrsp_progress("Configuring nodes..."); - my $retref = xCAT::Utils->runxcmd({command=>["kitnodeupdate"], node=>[$hostname], sequential=>[1]}, $request_command, 0, 2); + my $retref = {}; + setrsp_progress("Updating DNS entries"); + $retref = xCAT::Utils->runxcmd({command=>["makedns"], node=>[$hostname], arg=>['-d']}, $request_command, 0, 2); my $retstrref = parse_runxcmd_ret($retref); if ($::RUNCMD_RC != 0){ setrsp_progress("Warning: failed to call kit commands."); } + $retref = {}; + setrsp_progress("Updating hosts entries"); + $retref = xCAT::Utils->runxcmd({command=>["makehosts"], node=>[$hostname], arg=>['-d']}, $request_command, 0, 2); + $retref = {}; + $retstrref = parse_runxcmd_ret($retref); + if ($::RUNCMD_RC != 0){ + setrsp_progress("Warning: failed to call kit commands."); + } + + setrsp_progress("Re-creating nodes..."); + $retref = xCAT::Utils->runxcmd({command=>["kitnodeadd"], node=>[$hostname], macflag=>[1]}, $request_command, 0, 2); + $retstrref = parse_runxcmd_ret($retref); + if ($::RUNCMD_RC != 0){ + setrsp_progress("Warning: failed to call kit commands."); + } + # Update node's status. setrsp_progress("Updating node status..."); xCAT::Utils->runxcmd({command=>["updatenodestat"], node=>[$hostname], arg=>['defined']}, $request_command, -1, 2); @@ -1755,6 +1791,15 @@ sub gen_new_hostinfo_dict{ # Get node's provisioning method my $provmethod = xCAT::ProfiledNodeUtils->get_imageprofile_prov_method($args_dict{'imageprofile'}); + # Generate node's chain. + my %nodeprofiles = ('NetworkProfile' => $args_dict{'networkprofile'}, + 'ImageProfile' => $args_dict{'imageprofile'}); + if (defined $args_dict{'hardwareprofile'}) {$nodeprofiles{'HardwareProfile'} = $args_dict{'hardwareprofile'}} + (my $errcode, my $chainstr) = xCAT::ProfiledNodeUtils->gen_chain_for_profiles(\%nodeprofiles, 1); + if ($errcode != 0){ + return (0, "Failed to generate chain for nodes."); + } + # start to check windows nodes, product will indicate it is a windows node: win2k8r2.enterprise my ($osvers, $osprofile) = xCAT::ProfiledNodeUtils->get_imageprofile_prov_osvers($provmethod); my $product = undef; @@ -1899,23 +1944,10 @@ sub gen_new_hostinfo_dict{ my $hardwareprofile = $args_dict{'hardwareprofile'}; my $chain = $chaintab->getNodeAttribs($hardwareprofile, ['chain']); - if (exists $chain->{'chain'}) { - my $hardwareprofile_chain = $chain->{'chain'}; - $hostinfo_dict{$item}{"chain"} = $hardwareprofile_chain.',osimage='.$provmethod.":--noupdateinitrd"; - } - - else { - $hostinfo_dict{$item}{"chain"} = 'osimage='.$provmethod.":--noupdateinitrd"; - } + $hostinfo_dict{$item}{"chain"} = $chainstr; if (exists $netprofileattr{"bmc"}){ # Update BMC records. $hostinfo_dict{$item}{"mgt"} = "ipmi"; - if (index($hostinfo_dict{$item}{"chain"}, "runcmd=bmcsetup") == -1){ - $hostinfo_dict{$item}{"chain"} = 'runcmd=bmcsetup,'.$hostinfo_dict{$item}{"chain"}.':reboot4deploy'; - } - else{ - $hostinfo_dict{$item}{"chain"} = $hostinfo_dict{$item}{"chain"}.':reboot4deploy'; - } if (exists $ipshash{"bmc"}){ $hostinfo_dict{$item}{"bmc"} = $ipshash{"bmc"};