mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-29 17:23:08 +00:00
Merge pull request #3456 from robin2008/nodeset-disjoint
Fix #3088, Using 'disjointdhcps' site attribute to make nodeset request will only be handled on service node for nodes it manages
This commit is contained in:
commit
8fbf24d781
@ -110,8 +110,9 @@ site Attributes:
|
||||
dhcplease: The lease time for the dhcp client. The default value is 43200.
|
||||
|
||||
disjointdhcps: If set to '1', the .leases file on a service node only contains
|
||||
the nodes it manages. The default value is '0'.
|
||||
'0' value means include all the nodes in the subnet.
|
||||
the nodes it manages. And when 'sharedtftp' is disabled, nodeset handles
|
||||
boot loader configuration on a service node only for the nodes it manages.
|
||||
The default value is '0'. It means include all the nodes in the subnet.
|
||||
|
||||
pruneservices: Whether to enable service pruning when noderm is run (i.e.
|
||||
removing DHCP entries when noderm is executed)
|
||||
|
@ -19,7 +19,7 @@ Name
|
||||
****************
|
||||
|
||||
|
||||
\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ | \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ]
|
||||
\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ [\ **-a**\ ]| \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ]
|
||||
|
||||
\ **nodeset**\ \ *noderange*\ \ **osimage**\ [=\ *imagename*\ ] [\ **-**\ **-noupdateinitrd**\ ] [\ **-**\ **-ignorekernelchk**\ ]
|
||||
|
||||
@ -101,7 +101,7 @@ A user can supply their own scripts to be run on the mn or on the service node (
|
||||
|
||||
\ **stat**\
|
||||
|
||||
Display the current boot loader config file description for the nodes requested
|
||||
Display the current boot loader config file description for the nodes requested. When \ **disjointdhcps**\ is set, using \ **-a**\ to display them on all available service nodes.
|
||||
|
||||
|
||||
|
||||
|
@ -1645,10 +1645,14 @@ sub getNodeIPaddress
|
||||
{
|
||||
require xCAT::Table;
|
||||
my $nodetocheck = shift;
|
||||
my $port = shift;
|
||||
my $nodeip;
|
||||
if ($nodetocheck eq 'xCAT::NetworkUtils') { #was called with -> syntax
|
||||
$nodetocheck = shift;
|
||||
}
|
||||
|
||||
$nodeip = xCAT::NetworkUtils->getipaddr($nodetocheck);
|
||||
# Quick return if pass in an IP
|
||||
return $nodetocheck if (xCAT::NetworkUtils->isIpaddr($nodetocheck));
|
||||
|
||||
my $nodeip = xCAT::NetworkUtils->getipaddr($nodetocheck);
|
||||
if (!$nodeip)
|
||||
{
|
||||
my $hoststab = xCAT::Table->new('hosts');
|
||||
@ -1666,6 +1670,51 @@ sub getNodeIPaddress
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 checkNodeIPaddress
|
||||
Arguments:
|
||||
Node name only one at a time
|
||||
Returns: a hash object contains IP or Error
|
||||
Globals:
|
||||
none
|
||||
Example: my $ipresult = xCAT::NetworkUtils::checkNodeIPaddress($nodetocheck);
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub checkNodeIPaddress
|
||||
{
|
||||
require xCAT::Table;
|
||||
my $nodetocheck = shift;
|
||||
if ($nodetocheck eq 'xCAT::NetworkUtils') { #was called with -> syntax
|
||||
$nodetocheck = shift;
|
||||
}
|
||||
my $ret;
|
||||
|
||||
my $nodeip;
|
||||
my $hoststab = xCAT::Table->new('hosts');
|
||||
my $ent = $hoststab->getNodeAttribs($nodetocheck, ['ip']);
|
||||
if ($ent->{'ip'}) {
|
||||
$nodeip = $ent->{'ip'};
|
||||
}
|
||||
|
||||
# Get the IP from DNS
|
||||
my $dnsip = xCAT::NetworkUtils->getipaddr($nodetocheck);
|
||||
if (!$dnsip)
|
||||
{
|
||||
$ret->{'error'} = "The $nodetocheck can not be resolved.";
|
||||
$ret->{'ip'} = $nodeip if ($nodeip);
|
||||
} elsif (!$nodeip) {
|
||||
$ret->{'ip'} = $dnsip;
|
||||
} else {
|
||||
$ret->{'ip'} = $nodeip;
|
||||
$ret->{'error'} = "Defined IP address of $nodetocheck is inconsistent with DNS." if ($nodeip ne $dnsip);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1029,8 +1029,9 @@ passed as argument rather than by table value',
|
||||
" dhcpsetup: If set to 'n', it will skip the dhcp setup process in the nodeset cmd.\n\n" .
|
||||
" dhcplease: The lease time for the dhcp client. The default value is 43200.\n\n" .
|
||||
" disjointdhcps: If set to '1', the .leases file on a service node only contains\n" .
|
||||
" the nodes it manages. The default value is '0'.\n" .
|
||||
" '0' value means include all the nodes in the subnet.\n\n" .
|
||||
" the nodes it manages. And when 'sharedtftp' is disabled, nodeset handles\n" .
|
||||
" boot loader configuration on a service node only for the nodes it manages.\n" .
|
||||
" The default value is '0'. It means include all the nodes in the subnet.\n\n" .
|
||||
" pruneservices: Whether to enable service pruning when noderm is run (i.e.\n" .
|
||||
" removing DHCP entries when noderm is executed)\n\n" .
|
||||
" managedaddressmode: The mode of networking configuration during node provision.\n" .
|
||||
|
@ -2,6 +2,7 @@ package xCAT::Scope;
|
||||
|
||||
use xCAT::Utils;
|
||||
use xCAT::Table;
|
||||
use xCAT::TableUtils;
|
||||
use xCAT::ServiceNodeUtils qw(getSNList);
|
||||
|
||||
|
||||
@ -125,16 +126,17 @@ sub get_parallel_scope {
|
||||
=head3 get_broadcast_scope_with_parallel
|
||||
|
||||
Convert a request object to an array of multiple requests according to the
|
||||
splitted node range.
|
||||
splitted node range. Also it replicates the requests to all required service
|
||||
nodes or management node.
|
||||
|
||||
Arguments:
|
||||
Reference of request
|
||||
Callback: TODO, Optional, the Callback will be used to filter the nodes
|
||||
SN list: Array of target service nodes
|
||||
Returns: An array of requests
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my $reqs = xCAT::Scope->get_broadcast_scope($request);
|
||||
my $reqs = xCAT::Scope->get_broadcast_scope_with_parallel($request, \@snlist);
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -145,25 +147,118 @@ sub get_broadcast_scope_with_parallel {
|
||||
}
|
||||
#Exit if the packet has been preprocessed in its history
|
||||
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
||||
$req->{_xcatpreprocessed}->[0] = 1;
|
||||
|
||||
#Handle the one for current management/service node
|
||||
my $reqs = get_parallel_scope($req);
|
||||
my @requests = @$reqs;
|
||||
my $snlist = shift;
|
||||
|
||||
#Broadcast the request to other management/service nodes
|
||||
foreach (xCAT::ServiceNodeUtils->getSNList()) {
|
||||
if (xCAT::NetworkUtils->thishostisnot($_)) {
|
||||
my $xcatdest = $_;
|
||||
my $reqcopy = {%$req};
|
||||
$reqcopy->{'_xcatdest'} = $_;
|
||||
$reqcopy->{_xcatpreprocessed}->[0] = 1;
|
||||
#Apply callback to filter the node range in future.
|
||||
$reqs = get_parallel_scope($reqcopy);
|
||||
foreach (@$reqs) {
|
||||
push @requests, {%$_};
|
||||
}
|
||||
my $reqs = get_parallel_scope($req);
|
||||
|
||||
my @requests = (); # The request array will be return.
|
||||
push @requests, @$reqs;
|
||||
|
||||
# when this method is called on service node, it is required to broadcast to MN too.
|
||||
# get site.master from DB in order to dispatch to MN ( MN will not be added in servicenode table)
|
||||
if ( xCAT::Utils->isServiceNode() ) {
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("master");
|
||||
my $master = $entries[0];
|
||||
foreach (@$reqs) {
|
||||
my $reqcopy = {%$_};
|
||||
$reqcopy->{'_xcatdest'} = $master;
|
||||
push @requests, $reqcopy;
|
||||
}
|
||||
}
|
||||
|
||||
#Broadcast the request to all service nodes
|
||||
foreach (@$snlist) {
|
||||
my $xcatdest = $_;
|
||||
next unless (xCAT::NetworkUtils->thishostisnot($xcatdest));
|
||||
|
||||
foreach (@$reqs) {
|
||||
my $reqcopy = {%$_};
|
||||
$reqcopy->{'_xcatdest'} = $xcatdest;
|
||||
push @requests, $reqcopy;
|
||||
}
|
||||
}
|
||||
return \@requests;
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 get_broadcast_disjoint_scope_with_parallel
|
||||
|
||||
Convert a request object to an array of multiple requests according to the
|
||||
splitted node range. Also it replicates the requests to all required service
|
||||
nodes or management node, but the request to a service node will only contains
|
||||
the node range it manages.
|
||||
|
||||
Arguments:
|
||||
Reference of request
|
||||
SN hash: Hash of target service nodes => Managed CNs
|
||||
Special servers: Array of servers, those servers are required to handle whole noderange.
|
||||
Returns: An array of requests
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my $reqs = xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($request, \@snhash);
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub get_broadcast_disjoint_scope_with_parallel {
|
||||
my $req = shift;
|
||||
if ($req =~ /xCAT::Scope/) {
|
||||
$req = shift;
|
||||
}
|
||||
#Exit if the packet has been preprocessed in its history
|
||||
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
||||
$req->{_xcatpreprocessed}->[0] = 1;
|
||||
|
||||
my $sn_hash = shift;
|
||||
my $extras = shift;
|
||||
|
||||
my @requests = (); # The request array will be return.
|
||||
my $reqs = get_parallel_scope($req);
|
||||
|
||||
my $handled4me = 0; # indicate myself is already handled.
|
||||
my %prehandledhash = ();# the servers which is already handled.
|
||||
foreach (@$extras) {
|
||||
my $xcatdest = $_;
|
||||
if (xCAT::NetworkUtils->thishostisnot($xcatdest)) {
|
||||
# TODO, To avoid sending request to a multi-home server many times.
|
||||
foreach (@$reqs) {
|
||||
my $reqcopy = {%$_};
|
||||
$reqcopy->{'_xcatdest'} = $xcatdest;
|
||||
push @requests, $reqcopy;
|
||||
}
|
||||
$prehandledhash{$xcatdest} = 1;
|
||||
} elsif ($handled4me == 0) {
|
||||
push @requests, @$reqs;
|
||||
$handled4me = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#Broadcast the request to all available service nodes
|
||||
foreach (keys %$sn_hash) {
|
||||
my $xcatdest = $_;
|
||||
# to check if the SN already handled
|
||||
next if (exists($prehandledhash{$xcatdest}));
|
||||
|
||||
if (xCAT::NetworkUtils->thishostisnot($xcatdest)) {
|
||||
my $reqcopy = {%$req};
|
||||
$reqcopy->{'_xcatdest'} = $xcatdest;
|
||||
$reqcopy->{'node'} = $sn_hash->{$xcatdest};
|
||||
|
||||
$reqs = get_parallel_scope($reqcopy);
|
||||
push @requests, @$reqs;
|
||||
} elsif ($handled4me == 0) {
|
||||
my $reqcopy = {%$req};
|
||||
$reqcopy->{'node'} = $sn_hash->{$xcatdest};
|
||||
|
||||
$reqs = get_parallel_scope($reqcopy);
|
||||
push @requests, @$reqs;
|
||||
$handled4me = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return \@requests;
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,7 @@ Options:
|
||||
"Usage:
|
||||
Common:
|
||||
nodeset [-h|--help|-v|--version]
|
||||
nodeset <noderange> [shell|boot|runcmd=bmcsetup|osimage[=<imagename>]|offline|shutdown|stat]",
|
||||
nodeset <noderange> [shell|boot|runcmd=bmcsetup|osimage[=<imagename>]|offline|shutdown|stat [-a]]",
|
||||
"rmflexnode" =>
|
||||
"Usage:
|
||||
rmflexnode [-h|--help|-v|--version]
|
||||
|
@ -4,7 +4,7 @@ B<nodeset> - set the boot state for a noderange
|
||||
|
||||
=head1 B<Synopsis>
|
||||
|
||||
B<nodeset> I<noderange> [B<boot> | B<stat> | B<offline> | B<runcmd=bmcsetup> | B<osimage>[=I<imagename>] | B<shell> | B<shutdown>]
|
||||
B<nodeset> I<noderange> [B<boot> | B<stat> [B<-a>]| B<offline> | B<runcmd=bmcsetup> | B<osimage>[=I<imagename>] | B<shell> | B<shutdown>]
|
||||
|
||||
B<nodeset> I<noderange> B<osimage>[=I<imagename>] [B<--noupdateinitrd>] [B<--ignorekernelchk>]
|
||||
|
||||
@ -68,7 +68,7 @@ If you would like to run a task after deployment, you can define that task with
|
||||
|
||||
=item B<stat>
|
||||
|
||||
Display the current boot loader config file description for the nodes requested
|
||||
Display the current boot loader config file description for the nodes requested. When B<disjointdhcps> is set, using B<-a> to display them on all available service nodes.
|
||||
|
||||
=item B<runcmd=bmcsetup>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::grub2;
|
||||
use Data::Dumper;
|
||||
|
||||
use Sys::Syslog;
|
||||
use xCAT::Scope;
|
||||
use xCAT::Utils;
|
||||
@ -123,12 +123,10 @@ sub setstate {
|
||||
|
||||
# We are in the service node pools, print error if no facing ip.
|
||||
if (xCAT::InstUtils->is_me($sn)) {
|
||||
my @myself = xCAT::NetworkUtils->determinehostname();
|
||||
my $myname = $myself[ (scalar @myself) - 1 ];
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$myname: $ipfnd[1] on service node $sn"
|
||||
"$::myxcatname: $ipfnd[1] on service node $sn"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
@ -140,7 +138,7 @@ sub setstate {
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$myname: $ipfnd[1]"
|
||||
"$::myxcatname: $ipfnd[1]"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
@ -176,9 +174,9 @@ sub setstate {
|
||||
$kern->{kcmdline} .= " " . $cmdhashref->{volatile};
|
||||
}
|
||||
|
||||
my $pcfg;
|
||||
unless (-d "$tftpdir/boot/grub2") {
|
||||
mkpath("$tftpdir/boot/grub2");
|
||||
my $bootloader_root = "$tftpdir/boot/grub2";
|
||||
unless (-d "$bootloader_root") {
|
||||
mkpath("$bootloader_root");
|
||||
}
|
||||
my $nodemac;
|
||||
my %client_nethash = xCAT::DBobjUtils->getNetwkInfo([$node]);
|
||||
@ -186,9 +184,10 @@ sub setstate {
|
||||
my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']);
|
||||
|
||||
# remove the old boot configuration files and create a new one, but only if not offline directive
|
||||
system("find $tftpdir/boot/grub2/ -inum \$(stat --printf \%i $tftpdir/boot/grub2/$node 2>/dev/null) -exec rm -f {} \\; 2>/dev/null");
|
||||
system("find $bootloader_root/ -inum \$(stat --printf \%i $bootloader_root/$node 2>/dev/null) -exec rm -f {} \\; 2>/dev/null");
|
||||
my $pcfg;
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
open($pcfg, '>', $tftpdir . "/boot/grub2/" . $node);
|
||||
open($pcfg, '>', "$bootloader_root/" . $node);
|
||||
print $pcfg "#" . $cref->{currstate} . "\n";
|
||||
|
||||
if (($::XCATSITEVALS{xcatdebugmode} eq "1") or ($::XCATSITEVALS{xcatdebugmode} eq "2")) {
|
||||
@ -294,11 +293,6 @@ sub setstate {
|
||||
print $pcfg "}";
|
||||
close($pcfg);
|
||||
}
|
||||
my $inetn = xCAT::NetworkUtils->getipaddr($node);
|
||||
unless ($inetn) {
|
||||
syslog("local1|err", "xCAT unable to resolve IP for $node in grub2 plugin");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
close($pcfg);
|
||||
}
|
||||
@ -334,9 +328,9 @@ sub setstate {
|
||||
my $pname = "grub.cfg-" . sprintf("%02X%02X%02X%02X", @ipa);
|
||||
|
||||
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
|
||||
unlink($tftpdir . "/boot/grub2/" . $pname);
|
||||
unlink("$bootloader_root/" . $pname);
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname);
|
||||
link("$bootloader_root/" . $node, "$bootloader_root/" . $pname);
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,9 +353,9 @@ sub setstate {
|
||||
my $pname = "grub.cfg-01-" . $tmp;
|
||||
|
||||
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
|
||||
unlink($tftpdir . "/boot/grub2/" . $pname);
|
||||
unlink("$bootloader_root/" . $pname);
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname);
|
||||
link("$bootloader_root/" . $node, "$bootloader_root/" . $pname);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -402,12 +396,14 @@ sub preprocess_request {
|
||||
|
||||
#use Getopt::Long;
|
||||
my $HELP;
|
||||
my $ALLFLAG;
|
||||
my $VERSION;
|
||||
my $VERBOSE;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
if (!GetOptions('h|?|help' => \$HELP,
|
||||
'v|version' => \$VERSION,
|
||||
'a' =>\$ALLFLAG,
|
||||
'V' => \$VERBOSE #>>>>>>>used for trace log>>>>>>>
|
||||
)) {
|
||||
if ($usage{$command}) {
|
||||
@ -469,12 +465,12 @@ sub preprocess_request {
|
||||
xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN);
|
||||
unless (($args[0] eq 'stat') or ($args[0] eq 'enact')) {
|
||||
if ((@SN > 0) && (@CN > 0)) { # there are both SN and CN
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] =
|
||||
my %rsp;
|
||||
$rsp{errorcode}->[0] = 1;
|
||||
$rsp{error}->[0] =
|
||||
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback1);
|
||||
$callback1->(\%rsp);
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,10 +478,40 @@ sub preprocess_request {
|
||||
if ($req->{inittime}->[0]) {
|
||||
return [$req];
|
||||
}
|
||||
if (@CN > 0) { # if compute nodes broadcast to all servicenodes
|
||||
return xCAT::Scope->get_broadcast_scope_with_parallel($req);
|
||||
if (@CN > 0) { # if compute nodes only, then broadcast to servic enodes
|
||||
|
||||
my @sn = xCAT::ServiceNodeUtils->getSNList();
|
||||
unless ( @sn > 0 ) {
|
||||
return xCAT::Scope->get_parallel_scope($req)
|
||||
}
|
||||
|
||||
my $mynodeonly = 0;
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("disjointdhcps");
|
||||
my $t_entry = $entries[0];
|
||||
if (defined($t_entry)) {
|
||||
$mynodeonly = $t_entry;
|
||||
}
|
||||
$req->{'_disjointmode'} = [$mynodeonly];
|
||||
xCAT::MsgUtils->trace(0, "d", "grub2: disjointdhcps=$mynodeonly");
|
||||
|
||||
if ($mynodeonly == 0 || $ALLFLAG) { # broadcast to all service nodes
|
||||
return xCAT::Scope->get_broadcast_scope_with_parallel($req, \@sn);
|
||||
}
|
||||
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@CN, "xcat", "MN");
|
||||
my @dhcpsvrs = ();
|
||||
my $ntab = xCAT::Table->new('networks');
|
||||
if ($ntab) {
|
||||
foreach (@{ $ntab->getAllEntries() }) {
|
||||
next unless ($_->{dynamicrange});
|
||||
# if dynamicrange specified but dhcpserver was not - issue error message
|
||||
push @dhcpsvrs, $_->{dhcpserver} if ($_->{dhcpserver})
|
||||
}
|
||||
}
|
||||
return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash, \@dhcpsvrs);
|
||||
}
|
||||
}
|
||||
# Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs.
|
||||
return xCAT::Scope->get_parallel_scope($req);
|
||||
}
|
||||
|
||||
@ -496,19 +522,16 @@ sub process_request {
|
||||
$sub_req = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
%breaknetbootnodes = ();
|
||||
%normalnodes = ();
|
||||
%normalnodes = (); # It will be fill-up by method: setstate.
|
||||
|
||||
my @args;
|
||||
my @nodes;
|
||||
my @rnodes;
|
||||
|
||||
#>>>>>>>used for trace log start>>>>>>>
|
||||
my %opt;
|
||||
my $verbose_on_off = 0;
|
||||
if (ref($::XNBA_request->{arg})) {
|
||||
@args = @{ $::XNBA_request->{arg} };
|
||||
if (ref($request->{arg})) {
|
||||
@args = @{ $request->{arg} };
|
||||
} else {
|
||||
@args = ($::XNBA_request->{arg});
|
||||
@args = ($request->{arg});
|
||||
}
|
||||
@ARGV = @args;
|
||||
GetOptions('V' => \$opt{V});
|
||||
@ -516,6 +539,10 @@ sub process_request {
|
||||
|
||||
#>>>>>>>used for trace log end>>>>>>>
|
||||
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
$::myxcatname = $hostinfo[-1];
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: running on $::myxcatname");
|
||||
my @rnodes;
|
||||
if (ref($request->{node})) {
|
||||
@rnodes = @{ $request->{node} };
|
||||
} else {
|
||||
@ -528,61 +555,101 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
|
||||
#if not shared tftpdir, then filter, otherwise, set up everything
|
||||
if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
@nodes = ();
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
my $cur_xmaster = pop @hostinfo;
|
||||
xCAT::MsgUtils->trace(0, "d", "grub2: running on $cur_xmaster");
|
||||
|
||||
# Get current server managed node list
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN");
|
||||
my %managed = {};
|
||||
foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
|
||||
foreach (@rnodes) {
|
||||
if (xCAT::NetworkUtils->nodeonmynet($_)) {
|
||||
push @nodes, $_;
|
||||
if ($args[0] eq 'stat') {
|
||||
my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories
|
||||
my %nrhash = %{ $noderestab->getNodesAttribs(\@rnodes, [qw(tftpdir)]) };
|
||||
foreach my $node (@rnodes) {
|
||||
my %response;
|
||||
my $tftpdir;
|
||||
if ($nrhash{$node}->[0] and $nrhash{$node}->[0]->{tftpdir}) {
|
||||
$tftpdir = $nrhash{$node}->[0]->{tftpdir};
|
||||
} else {
|
||||
my $msg = "grub2 configuration file was not created for node [$_] because sharedtftp attribute is not set and the node is not on same network as this xcatmaster";
|
||||
if ( $cur_xmaster ) {
|
||||
$msg .= ": $cur_xmaster";
|
||||
}
|
||||
if ( exists( $managed{$_} ) ) {
|
||||
# report error when it is under my control but I cannot handle it.
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = $msg;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->message("S", $msg);
|
||||
}
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $node;
|
||||
$response{node}->[0]->{data}->[0] = getstate($node, $tftpdir);
|
||||
$callback->(\%response);
|
||||
}
|
||||
} else {
|
||||
@nodes = @rnodes;
|
||||
}
|
||||
|
||||
#>>>>>>>used for trace log>>>>>>>
|
||||
my $str_node = join(" ", @nodes);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: nodes are $str_node");
|
||||
|
||||
# return directly if no nodes in the same network
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: grub2 netboot: no valid nodes. Stop the operation on this server.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref($request->{arg})) {
|
||||
@args = @{ $request->{arg} };
|
||||
my @nodes = ();
|
||||
# Filter those nodes which have bad DNS: not resolvable or inconsistent IP
|
||||
my %failurenodes = ();
|
||||
my %preparednodes = ();
|
||||
foreach (@rnodes) {
|
||||
my $ipret = xCAT::NetworkUtils->checkNodeIPaddress($_);
|
||||
my $errormsg = $ipret->{'error'};
|
||||
my $nodeip = $ipret->{'ip'};
|
||||
if ($errormsg) {# Add the node to failure set
|
||||
xCAT::MsgUtils->trace(0, "E", "grub2: Defined IP address of $_ is $nodeip. $errormsg");
|
||||
unless ($nodeip) {
|
||||
$failurenodes{$_} = 1;
|
||||
}
|
||||
}
|
||||
if ($nodeip) {
|
||||
$preparednodes{$_} = $nodeip;
|
||||
}
|
||||
}
|
||||
|
||||
#if not shared tftpdir, then filter, otherwise, set up everything
|
||||
if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
# Filter those nodes not in the same subnet, and print error message in log file.
|
||||
foreach (keys %preparednodes) {
|
||||
# Only handle its boot configuration files if the node in same subnet
|
||||
if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) {
|
||||
push @nodes, $_;
|
||||
} else {
|
||||
xCAT::MsgUtils->trace(0, "W", "grub2: configuration file was not created for [$_] because the node is not on the same network as this server");
|
||||
delete $preparednodes{$_};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@args = ($request->{arg});
|
||||
@nodes = keys %preparednodes;
|
||||
}
|
||||
|
||||
my $str_node = join(" ", @nodes);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: nodes are $str_node") if ($str_node);
|
||||
|
||||
# Return directly if no nodes in the same network, need to report error on console if its managed nodes are not handled.
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: grub2 netboot: no valid nodes. Stop the operation on this server.");
|
||||
|
||||
# If non-shared tftproot and non disjoint mode, need to figure out if no nodes here is a normal case.
|
||||
if ($request->{'_disparatetftp'}->[0] && $request->{'_disjointmode'}->[0] != 1) {
|
||||
# Find out which nodes are really mine only when not sharedtftp and not disjoint mode.
|
||||
my %iphash = ();
|
||||
# flag the IPs or names in iphash
|
||||
foreach (@hostinfo) { $iphash{$_} = 1; }
|
||||
|
||||
# Get managed node list under current server
|
||||
# The node will be under under 'site.master' if no 'noderes.servicenode' is defined
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN");
|
||||
my $req2manage = 0;
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
$req2manage = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
# Okay, now report error as no nodes are handled.
|
||||
if ($req2manage == 0) {
|
||||
xCAT::MsgUtils->trace(0, "d", "grub2: No nodes are required to be managed on this server");
|
||||
return;
|
||||
}
|
||||
}
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed to generate grub2 configurations for some node(s) on $::myxcatname. Check xCAT log file for more details.";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
#now run the begin part of the prescripts
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') {
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact') {
|
||||
$errored = 0;
|
||||
if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: the call is distrubuted to the service node already, so only need to handles my own children");
|
||||
if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handle my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: the call is distrubuted to the service node already, so only need to handle my own children");
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue runbeginpre request");
|
||||
$sub_req->({ command => ['runbeginpre'],
|
||||
node => \@nodes,
|
||||
@ -609,7 +676,7 @@ sub process_request {
|
||||
if (!$inittime) { $inittime = 0; }
|
||||
|
||||
my %bphash;
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') {
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact') {
|
||||
$errored = 0;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue setdestiny request");
|
||||
$sub_req->({ command => ['setdestiny'],
|
||||
@ -619,11 +686,12 @@ sub process_request {
|
||||
bootparams => \%bphash
|
||||
}, \&pass_along);
|
||||
if ($errored) {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Failed in processing setdestiny. Processing will not continue.");
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Failed in processing setdestiny. Processing will not continue.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: starting to handle configuration...");
|
||||
my $chaintab = xCAT::Table->new('chain', -create => 1);
|
||||
my $chainhash = $chaintab->getNodesAttribs(\@nodes, ['currstate']);
|
||||
my $noderestab = xCAT::Table->new('noderes', -create => 1);
|
||||
@ -649,10 +717,7 @@ sub process_request {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $_;
|
||||
if ($args[0] eq 'stat') {
|
||||
$response{node}->[0]->{data}->[0] = getstate($_, $tftpdir);
|
||||
$callback->(\%response);
|
||||
} elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate
|
||||
if ($args[0]) { # Send it on to the destiny plugin, then setstate
|
||||
my $ent = $typehash->{$_}->[0];
|
||||
my $osimgname = $ent->{'provmethod'};
|
||||
my $linuximghash = undef;
|
||||
@ -668,11 +733,11 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
} # end of foreach node
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Finish to handle configurations");
|
||||
|
||||
my @normalnodeset = keys %normalnodes;
|
||||
my @breaknetboot = keys %breaknetbootnodes;
|
||||
|
||||
#print "grub2 :inittime=$inittime; normalnodeset=@normalnodeset; breaknetboot=@breaknetboot\n";
|
||||
my %osimagenodehash;
|
||||
for my $nn (@normalnodeset) {
|
||||
|
||||
@ -693,7 +758,7 @@ sub process_request {
|
||||
}
|
||||
|
||||
#Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time
|
||||
unless (($args[0] eq 'stat') || ($inittime) || ($args[0] eq 'offline')) {
|
||||
unless (($inittime) || ($args[0] eq 'offline')) {
|
||||
foreach my $osimage (keys %osimagenodehash) {
|
||||
|
||||
#TOTO check the existence of grub2 executable files for corresponding arch
|
||||
@ -793,7 +858,7 @@ sub process_request {
|
||||
}
|
||||
|
||||
#now run the end part of the prescripts
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact')
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact')
|
||||
$errored = 0;
|
||||
if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue runendpre request");
|
||||
@ -814,6 +879,16 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Return error codes if there are failed nodes
|
||||
if (%failurenodes) {
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed to generate grub2 configurations for some node(s) on $::myxcatname. Check xCAT log file for more details.";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
@ -78,7 +78,7 @@ sub setstate {
|
||||
|
||||
=pod
|
||||
|
||||
This function will manipulate the yaboot structure to match what the noderes/chain tables indicate the node should be booting.
|
||||
This function will manipulate the petitboot structure to match what the noderes/chain tables indicate the node should be booting.
|
||||
|
||||
=cut
|
||||
|
||||
@ -125,12 +125,10 @@ sub setstate {
|
||||
|
||||
# We are in the service node pools, print error if no facing ip.
|
||||
if (xCAT::InstUtils->is_me($sn)) {
|
||||
my @myself = xCAT::NetworkUtils->determinehostname();
|
||||
my $myname = $myself[ (scalar @myself) - 1 ];
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$myname: $ipfnd[1] on service node $sn"
|
||||
"$::myxcatname: $ipfnd[1] on service node $sn"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
@ -142,7 +140,7 @@ sub setstate {
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$myname: $ipfnd[1]"
|
||||
"$::myxcatname: $ipfnd[1]"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
@ -170,18 +168,19 @@ sub setstate {
|
||||
}
|
||||
}
|
||||
|
||||
my $pcfg;
|
||||
unless (-d "$tftpdir/petitboot") {
|
||||
mkpath("$tftpdir/petitboot");
|
||||
my $bootloader_root = "$tftpdir/petitboot";
|
||||
unless (-d "$bootloader_root") {
|
||||
mkpath("$bootloader_root");
|
||||
}
|
||||
my $nodemac;
|
||||
|
||||
my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']);
|
||||
|
||||
my $pcfg;
|
||||
# remove the old boot configuration file and create a new one, but only if not offline directive
|
||||
unlink($tftpdir . "/petitboot/" . $node);
|
||||
unlink("$bootloader_root/" . $node);
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
open($pcfg, '>', $tftpdir . "/petitboot/" . $node);
|
||||
open($pcfg, '>', "$bootloader_root/" . $node);
|
||||
print $pcfg "#" . $cref->{currstate} . "\n";
|
||||
}
|
||||
$normalnodes{$node} = 1; #Assume a normal netboot (well, normal dhcp,
|
||||
@ -217,18 +216,13 @@ sub setstate {
|
||||
print $pcfg "\tappend \"" . $kern->{kcmdline} . "\"\n";
|
||||
}
|
||||
close($pcfg);
|
||||
my $inetn = xCAT::NetworkUtils->getipaddr($node);
|
||||
unless ($inetn) {
|
||||
syslog("local1|err", "xCAT unable to resolve IP for $node in petitboot plugin");
|
||||
return;
|
||||
}
|
||||
} else { #TODO: actually, should possibly default to xCAT image?
|
||||
#print $pcfg "bye\n";
|
||||
close($pcfg);
|
||||
}
|
||||
my $ip = xCAT::NetworkUtils->getipaddr($node);
|
||||
unless ($ip) {
|
||||
syslog("local1|err", "xCAT unable to resolve IP in petitboot plugin");
|
||||
syslog("local1|err", "xCAT unable to resolve IP for $node in petitboot plugin");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -237,9 +231,9 @@ sub setstate {
|
||||
$pname = uc($pname);
|
||||
|
||||
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
|
||||
unlink($tftpdir . "/" . $pname);
|
||||
unlink("$tftpdir/" . $pname);
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
link($tftpdir . "/petitboot/" . $node, $tftpdir . "/" . $pname);
|
||||
link("$bootloader_root/" . $node, "$tftpdir/" . $pname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -283,12 +277,14 @@ sub preprocess_request {
|
||||
|
||||
#use Getopt::Long;
|
||||
my $HELP;
|
||||
my $ALLFLAG;
|
||||
my $VERSION;
|
||||
my $VERBOSE;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
if (!GetOptions('h|?|help' => \$HELP,
|
||||
'v|version' => \$VERSION,
|
||||
'a' =>\$ALLFLAG,
|
||||
'V' => \$VERBOSE #>>>>>>>used for trace log>>>>>>>
|
||||
)) {
|
||||
if ($usage{$command}) {
|
||||
@ -334,6 +330,13 @@ sub preprocess_request {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($ARGV[0] ne "stat" && $ALLFLAG) {
|
||||
my %rsp;
|
||||
$rsp{error}->[0] = "'-a' could only be used with 'stat' subcommand.";
|
||||
$rsp{errorcode}->[0] = 1;
|
||||
$callback1->(\%rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
#Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when
|
||||
#if they specify no sharedtftp in site table
|
||||
@ -346,23 +349,55 @@ sub preprocess_request {
|
||||
my @SN;
|
||||
my @CN;
|
||||
xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN);
|
||||
if ((@SN > 0) && (@CN > 0)) { # there are both SN and CN
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] =
|
||||
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback1);
|
||||
return;
|
||||
|
||||
unless (($args[0] eq 'stat') or ($args[0] eq 'enact')) {
|
||||
if ((@SN > 0) && (@CN > 0)) { # there are both SN and CN
|
||||
my %rsp;
|
||||
$rsp{errorcode}->[0] = 1;
|
||||
$rsp{error}->[0] =
|
||||
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
|
||||
$callback1->(\%rsp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$req->{'_disparatetftp'} = [1];
|
||||
if ($req->{inittime}->[0]) {
|
||||
return [$req];
|
||||
}
|
||||
if (@CN > 0) { # if compute nodes broadcast to all servicenodes
|
||||
return xCAT::Scope->get_broadcast_scope_with_parallel($req);
|
||||
if (@CN > 0) { # if compute nodes only, then broadcast to servic enodes
|
||||
|
||||
my @sn = xCAT::ServiceNodeUtils->getSNList();
|
||||
unless ( @sn > 0 ) {
|
||||
return xCAT::Scope->get_parallel_scope($req)
|
||||
}
|
||||
|
||||
my $mynodeonly = 0;
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("disjointdhcps");
|
||||
my $t_entry = $entries[0];
|
||||
if (defined($t_entry)) {
|
||||
$mynodeonly = $t_entry;
|
||||
}
|
||||
$req->{'_disjointmode'} = [$mynodeonly];
|
||||
xCAT::MsgUtils->trace(0, "d", "petitboot: disjointdhcps=$mynodeonly");
|
||||
|
||||
if ($mynodeonly == 0 || $ALLFLAG) { # broadcast to all service nodes
|
||||
return xCAT::Scope->get_broadcast_scope_with_parallel($req, \@sn);
|
||||
}
|
||||
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@CN, "xcat", "MN");
|
||||
my @dhcpsvrs = ();
|
||||
my $ntab = xCAT::Table->new('networks');
|
||||
if ($ntab) {
|
||||
foreach (@{ $ntab->getAllEntries() }) {
|
||||
next unless ($_->{dynamicrange});
|
||||
# if dynamicrange specified but dhcpserver was not - issue error message
|
||||
push @dhcpsvrs, $_->{dhcpserver} if ($_->{dhcpserver})
|
||||
}
|
||||
}
|
||||
return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash, \@dhcpsvrs);
|
||||
}
|
||||
}
|
||||
# Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs.
|
||||
return xCAT::Scope->get_parallel_scope($req);
|
||||
}
|
||||
|
||||
@ -374,16 +409,16 @@ sub process_request {
|
||||
$sub_req = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
%breaknetbootnodes = ();
|
||||
%normalnodes = ();
|
||||
%normalnodes = (); # It will be fill-up by method: setstate.
|
||||
|
||||
#>>>>>>>used for trace log start>>>>>>>
|
||||
my @args = ();
|
||||
my %opt;
|
||||
my $verbose_on_off = 0;
|
||||
if (ref($::request->{arg})) {
|
||||
@args = @{ $::request->{arg} };
|
||||
if (ref($request->{arg})) {
|
||||
@args = @{ $request->{arg} };
|
||||
} else {
|
||||
@args = ($::request->{arg});
|
||||
@args = ($request->{arg});
|
||||
}
|
||||
@ARGV = @args;
|
||||
GetOptions('V' => \$opt{V});
|
||||
@ -394,7 +429,9 @@ sub process_request {
|
||||
if ($::XCATSITEVALS{"httpmethod"}) { $httpmethod = $::XCATSITEVALS{"httpmethod"}; }
|
||||
if ($::XCATSITEVALS{"httpport"}) { $httpport = $::XCATSITEVALS{"httpport"}; }
|
||||
|
||||
my @nodes;
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
$::myxcatname = $hostinfo[-1];
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: running on $::myxcatname");
|
||||
my @rnodes;
|
||||
if (ref($request->{node})) {
|
||||
@rnodes = @{ $request->{node} };
|
||||
@ -408,61 +445,101 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
|
||||
#if not shared tftpdir, then filter, otherwise, set up everything
|
||||
if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
@nodes = ();
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
my $cur_xmaster = pop @hostinfo;
|
||||
xCAT::MsgUtils->trace(0, "d", "petitboot: running on $cur_xmaster");
|
||||
|
||||
# Get current server managed node list
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN");
|
||||
my %managed = {};
|
||||
foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
|
||||
foreach (@rnodes) {
|
||||
if (xCAT::NetworkUtils->nodeonmynet($_)) {
|
||||
push @nodes, $_;
|
||||
if ($args[0] eq 'stat') {
|
||||
my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories
|
||||
my %nrhash = %{ $noderestab->getNodesAttribs(\@rnodes, [qw(tftpdir)]) };
|
||||
foreach my $node (@rnodes) {
|
||||
my %response;
|
||||
my $tftpdir;
|
||||
if ($nrhash{$node}->[0] and $nrhash{$node}->[0]->{tftpdir}) {
|
||||
$tftpdir = $nrhash{$node}->[0]->{tftpdir};
|
||||
} else {
|
||||
my $msg = "petitboot configuration file was not created for node [$_] because sharedtftp attribute is not set and the node is not on same network as this xcatmaster";
|
||||
if ( $cur_xmaster ) {
|
||||
$msg .= ": $cur_xmaster";
|
||||
}
|
||||
if ( exists( $managed{$_} ) ) {
|
||||
# report error when it is under my control but I cannot handle it.
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = $msg;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->message("S", $msg);
|
||||
}
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $node;
|
||||
$response{node}->[0]->{data}->[0] = getstate($node, $tftpdir);
|
||||
$callback->(\%response);
|
||||
}
|
||||
} else {
|
||||
@nodes = @rnodes;
|
||||
}
|
||||
|
||||
#>>>>>>>used for trace log>>>>>>>
|
||||
my $str_node = join(" ", @nodes);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: nodes are $str_node");
|
||||
|
||||
# return directly if no nodes in the same network
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: no valid nodes. Stop the operation on this server.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref($request->{arg})) {
|
||||
@args = @{ $request->{arg} };
|
||||
my @nodes = ();
|
||||
# Filter those nodes which have bad DNS: not resolvable or inconsistent IP
|
||||
my %failurenodes = ();
|
||||
my %preparednodes = ();
|
||||
foreach (@rnodes) {
|
||||
my $ipret = xCAT::NetworkUtils->checkNodeIPaddress($_);
|
||||
my $errormsg = $ipret->{'error'};
|
||||
my $nodeip = $ipret->{'ip'};
|
||||
if ($errormsg) {# Add the node to failure set
|
||||
xCAT::MsgUtils->trace(0, "E", "petitboot: Defined IP address of $_ is $nodeip. $errormsg");
|
||||
unless ($nodeip) {
|
||||
$failurenodes{$_} = 1;
|
||||
}
|
||||
}
|
||||
if ($nodeip) {
|
||||
$preparednodes{$_} = $nodeip;
|
||||
}
|
||||
}
|
||||
|
||||
#if not shared tftpdir, then filter, otherwise, set up everything
|
||||
if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
# Filter those nodes not in the same subnet, and print error message in log file.
|
||||
foreach (keys %preparednodes) {
|
||||
# Only handle its boot configuration files if the node in same subnet
|
||||
if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) {
|
||||
push @nodes, $_;
|
||||
} else {
|
||||
xCAT::MsgUtils->trace(0, "W", "petitboot: configuration file was not created for [$_] because the node is not on the same network as this server");
|
||||
delete $preparednodes{$_};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@args = ($request->{arg});
|
||||
@nodes = keys %preparednodes;
|
||||
}
|
||||
|
||||
my $str_node = join(" ", @nodes);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: nodes are $str_node") if ($str_node);
|
||||
|
||||
# Return directly if no nodes in the same network, need to report error on console if its managed nodes are not handled.
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: no valid nodes. Stop the operation on this server.");
|
||||
|
||||
# If non-shared tftproot and non disjoint mode, need to figure out if no nodes here is a normal case.
|
||||
if ($request->{'_disparatetftp'}->[0] && $request->{'_disjointmode'}->[0] != 1) {
|
||||
# Find out which nodes are really mine only when not sharedtftp and not disjoint mode.
|
||||
my %iphash = ();
|
||||
# flag the IPs or names in iphash
|
||||
foreach (@hostinfo) { $iphash{$_} = 1; }
|
||||
|
||||
# Get managed node list under current server
|
||||
# The node will be under under 'site.master' if no 'noderes.servicenode' is defined
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN");
|
||||
my $req2manage = 0;
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
$req2manage = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($req2manage == 0) {
|
||||
#No nodes are required to be handled, quit without error.
|
||||
return;
|
||||
}
|
||||
}
|
||||
# Okay, now report error as no nodes are handled.
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed to generate petitboot configurations for some node(s) on $::myxcatname. Check xCAT log file for more details.";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
#now run the begin part of the prescripts
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') {
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact') {
|
||||
$errored = 0;
|
||||
if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: the call is distrubuted to the service node already, so only need to handles my own children");
|
||||
if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handle my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: the call is distrubuted to the service node already, so only need to handle my own children");
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runbeginpre request");
|
||||
$sub_req->({ command => ['runbeginpre'],
|
||||
node => \@nodes,
|
||||
@ -471,7 +548,7 @@ sub process_request {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: nodeset did not distribute to the service node");
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runbeginpre request");
|
||||
$sub_req->({ command => ['runbeginpre'],
|
||||
node => \@rnodes,
|
||||
node => \@nodes,
|
||||
arg => [ $args[0] ] }, \&pass_along);
|
||||
}
|
||||
if ($errored) {
|
||||
@ -489,7 +566,7 @@ sub process_request {
|
||||
if (!$inittime) { $inittime = 0; }
|
||||
|
||||
my %bphash;
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') {
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact') {
|
||||
$errored = 0;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue setdestiny request");
|
||||
$sub_req->({ command => ['setdestiny'],
|
||||
@ -515,6 +592,8 @@ sub process_request {
|
||||
});
|
||||
xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: clear node(s): @nodes boot device setting.");
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: starting to handle configuration...");
|
||||
my $chaintab = xCAT::Table->new('chain', -create => 1);
|
||||
my $chainhash = $chaintab->getNodesAttribs(\@nodes, ['currstate']);
|
||||
my $noderestab = xCAT::Table->new('noderes', -create => 1);
|
||||
@ -538,13 +617,10 @@ sub process_request {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $_;
|
||||
if ($args[0] eq 'stat') {
|
||||
$response{node}->[0]->{data}->[0] = getstate($_, $tftpdir);
|
||||
$callback->(\%response);
|
||||
} elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate
|
||||
if ($args[0]) { # send it on to the destiny plugin, then setstate
|
||||
my $ent = $typehash->{$_}->[0];
|
||||
my $osimgname = $ent->{'provmethod'};
|
||||
my $linuximghash = $linuximghash = $linuximgtab->getAttribs({ imagename => $osimgname }, 'boottarget', 'addkcmdline');
|
||||
my $linuximghash = $linuximgtab->getAttribs({ imagename => $osimgname }, 'boottarget', 'addkcmdline');
|
||||
|
||||
|
||||
($rc, $errstr) = setstate($_, \%bphash, $chainhash, $machash, $tftpdir, $nodereshash, $linuximghash);
|
||||
@ -555,11 +631,10 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
} # end of foreach node
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Finish to handle configurations");
|
||||
|
||||
my @normalnodeset = keys %normalnodes;
|
||||
my @breaknetboot = keys %breaknetbootnodes;
|
||||
|
||||
#print "yaboot:inittime=$inittime; normalnodeset=@normalnodeset; breaknetboot=@breaknetboot\n";
|
||||
my %osimagenodehash;
|
||||
for my $nn (@normalnodeset) {
|
||||
|
||||
@ -570,7 +645,7 @@ sub process_request {
|
||||
}
|
||||
|
||||
#Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time
|
||||
unless (($args[0] eq 'stat') || ($inittime) || ($args[0] eq 'offline')) {
|
||||
unless (($inittime) || ($args[0] eq 'offline')) {
|
||||
|
||||
#dhcp stuff
|
||||
my $do_dhcpsetup = 1;
|
||||
@ -580,16 +655,17 @@ sub process_request {
|
||||
if ($t_entry =~ /0|n|N/) { $do_dhcpsetup = 0; }
|
||||
}
|
||||
if ($do_dhcpsetup) {
|
||||
if ($::request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'], arg => ['-l'],
|
||||
node => \@normalnodeset }, $callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
node => \@normalnodeset }, $callback);
|
||||
}
|
||||
my @parameter;
|
||||
push @parameter, '-l' if ($::request->{'_disparatetftp'}->[0]);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request");
|
||||
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
arg => \@parameter,
|
||||
node => \@normalnodeset }, $callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: dhcpsetup=$do_dhcpsetup");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($args[0] eq 'offline') {
|
||||
@ -599,7 +675,7 @@ sub process_request {
|
||||
}
|
||||
|
||||
#now run the end part of the prescripts
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact')
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact')
|
||||
$errored = 0;
|
||||
if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runendpre request");
|
||||
@ -609,7 +685,7 @@ sub process_request {
|
||||
} else { #nodeset did not distribute to the service node, here we need to let runednpre to distribute the nodes to their masters
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runendpre request");
|
||||
$sub_req->({ command => ['runendpre'],
|
||||
node => \@rnodes,
|
||||
node => \@nodes,
|
||||
arg => [ $args[0] ] }, \&pass_along);
|
||||
}
|
||||
if ($errored) {
|
||||
@ -620,6 +696,15 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Return error codes if there are failed nodes
|
||||
if (%failurenodes) {
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed to generate petitboot configurations for some node(s) on $::myxcatname. Check xCAT log file for more details.";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
@ -331,10 +331,12 @@ sub preprocess_request {
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
my $HELP;
|
||||
my $ALLFLAG;
|
||||
my $VERSION;
|
||||
my $VERBOSE;
|
||||
if (!GetOptions('h|?|help' => \$HELP,
|
||||
'v|version' => \$VERSION,
|
||||
'a' =>\$ALLFLAG,
|
||||
'V' => \$VERBOSE #>>>>>>>used for trace log>>>>>>>
|
||||
)) {
|
||||
if ($usage{$command}) {
|
||||
@ -380,6 +382,13 @@ sub preprocess_request {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($ARGV[0] ne "stat" && $ALLFLAG) {
|
||||
my %rsp;
|
||||
$rsp{error}->[0] = "'-a' could only be used with 'stat' subcommand.";
|
||||
$rsp{errorcode}->[0] = 1;
|
||||
$callback1->(\%rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
#Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when
|
||||
#they specify no sharedtftp in site table
|
||||
@ -394,12 +403,12 @@ sub preprocess_request {
|
||||
xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN);
|
||||
unless (($args[0] eq 'stat') or ($args[0] eq 'enact')) { # mix is ok for these options
|
||||
if ((@SN > 0) && (@CN > 0)) { # there are both SN and CN
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] =
|
||||
my %rsp;
|
||||
$rsp{errorcode}->[0] = 1;
|
||||
$rsp{error}->[0] =
|
||||
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback1);
|
||||
$callback1->(\%rsp);
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,9 +417,39 @@ sub preprocess_request {
|
||||
return [$req];
|
||||
}
|
||||
if (@CN > 0) { # if compute nodes broadcast to all servicenodes
|
||||
return xCAT::Scope->get_broadcast_scope_with_parallel($req);
|
||||
|
||||
my @sn = xCAT::ServiceNodeUtils->getSNList();
|
||||
unless ( @sn > 0 ) {
|
||||
return xCAT::Scope->get_parallel_scope($req)
|
||||
}
|
||||
|
||||
my $mynodeonly = 0;
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("disjointdhcps");
|
||||
my $t_entry = $entries[0];
|
||||
if (defined($t_entry)) {
|
||||
$mynodeonly = $t_entry;
|
||||
}
|
||||
$req->{'_disjointmode'} = [$mynodeonly];
|
||||
xCAT::MsgUtils->trace(0, "d", "xnba: disjointdhcps=$mynodeonly");
|
||||
|
||||
if ($mynodeonly == 0 || $ALLFLAG) { # broadcast to all service nodes
|
||||
return xCAT::Scope->get_broadcast_scope_with_parallel($req, \@sn);
|
||||
}
|
||||
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@CN, "xcat", "MN");
|
||||
my @dhcpsvrs = ();
|
||||
my $ntab = xCAT::Table->new('networks');
|
||||
if ($ntab) {
|
||||
foreach (@{ $ntab->getAllEntries() }) {
|
||||
next unless ($_->{dynamicrange});
|
||||
# if dynamicrange specified but dhcpserver was not - issue error message
|
||||
push @dhcpsvrs, $_->{dhcpserver} if ($_->{dhcpserver})
|
||||
}
|
||||
}
|
||||
return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash, \@dhcpsvrs);
|
||||
}
|
||||
}
|
||||
# Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs.
|
||||
return xCAT::Scope->get_parallel_scope($req);
|
||||
}
|
||||
|
||||
@ -437,12 +476,14 @@ sub process_request {
|
||||
|
||||
#>>>>>>>used for trace log end>>>>>>>
|
||||
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
$::myxcatname = $hostinfo[-1];
|
||||
xCAT::MsgUtils->trace(0, "d", "xnba: running on $::myxcatname");
|
||||
if (ref($::XNBA_request->{node})) {
|
||||
@rnodes = @{ $::XNBA_request->{node} };
|
||||
} else {
|
||||
if ($::XNBA_request->{node}) { @rnodes = ($::XNBA_request->{node}); }
|
||||
}
|
||||
|
||||
unless (@rnodes) {
|
||||
if ($usage{ $::XNBA_request->{command}->[0] }) {
|
||||
$::XNBA_callback->({ data => $usage{ $::XNBA_request->{command}->[0] } });
|
||||
@ -450,60 +491,98 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
|
||||
#if not shared, then help sync up
|
||||
if ($::XNBA_request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
@nodes = ();
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
my $cur_xmaster = pop @hostinfo;
|
||||
xCAT::MsgUtils->trace(0, "d", "xnba: running on $cur_xmaster");
|
||||
|
||||
# Get current server managed node list
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN");
|
||||
my %managed = {};
|
||||
foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
|
||||
# Whatever the node managed by this xcatmaster explicitly, if the node in same subnet, we need to handle its boot configuration files
|
||||
foreach (@rnodes) {
|
||||
if (xCAT::NetworkUtils->nodeonmynet($_)) {
|
||||
push @nodes, $_;
|
||||
if ($args[0] eq 'stat') {
|
||||
my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories
|
||||
my %nrhash = %{ $noderestab->getNodesAttribs(\@rnodes, [qw(tftpdir)]) };
|
||||
foreach my $node (@rnodes) {
|
||||
my %response;
|
||||
my $tftpdir;
|
||||
if ($nrhash{$node}->[0] and $nrhash{$node}->[0]->{tftpdir}) {
|
||||
$tftpdir = $nrhash{$node}->[0]->{tftpdir};
|
||||
} else {
|
||||
my $msg = "xnba configuration file was not created for node [$_] because sharedtftp attribute is not set and the node is not on same network as this xcatmaster";
|
||||
if ( $cur_xmaster ) {
|
||||
$msg .= ": $cur_xmaster";
|
||||
}
|
||||
if ( exists( $managed{$_} ) ) {
|
||||
# report error when it is under my control but I cannot handle it.
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = $msg;
|
||||
xCAT::MsgUtils->message("E", $rsp, $::XNBA_callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->message("S", $msg);
|
||||
}
|
||||
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $node;
|
||||
$response{node}->[0]->{data}->[0] = getstate($node, $tftpdir);
|
||||
$::XNBA_callback->(\%response);
|
||||
}
|
||||
} else {
|
||||
@nodes = @rnodes;
|
||||
}
|
||||
|
||||
#>>>>>>>used for trace log>>>>>>>
|
||||
my $str_node = join(" ", @nodes);
|
||||
xCAT::MsgUtils->trace(0, "d", "xnba: nodes are $str_node");
|
||||
|
||||
# return directly if no nodes in the same network
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: xnba netboot: no valid nodes. Stop the operation on this server.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref($::XNBA_request->{arg})) {
|
||||
@args = @{ $::XNBA_request->{arg} };
|
||||
my @nodes = ();
|
||||
# Filter those nodes which have bad DNS: not resolvable or inconsistent IP
|
||||
my %failurenodes = ();
|
||||
my %preparednodes = ();
|
||||
foreach (@rnodes) {
|
||||
my $ipret = xCAT::NetworkUtils->checkNodeIPaddress($_);
|
||||
my $errormsg = $ipret->{'error'};
|
||||
my $nodeip = $ipret->{'ip'};
|
||||
if ($errormsg) {# Add the node to failure set
|
||||
xCAT::MsgUtils->trace(0, "E", "xnba: Defined IP address of $_ is $nodeip. $errormsg");
|
||||
unless ($nodeip) {
|
||||
$failurenodes{$_} = 1;
|
||||
}
|
||||
}
|
||||
if ($nodeip) {
|
||||
$preparednodes{$_} = $nodeip;
|
||||
}
|
||||
}
|
||||
|
||||
#if not shared tftpdir, then filter, otherwise, set up everything
|
||||
if ($::XNBA_request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
# Filter those nodes not in the same subnet, and print error message in log file.
|
||||
foreach (keys %preparednodes) {
|
||||
# Only handle its boot configuration files if the node in same subnet
|
||||
if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) {
|
||||
push @nodes, $_;
|
||||
} else {
|
||||
xCAT::MsgUtils->trace(0, "W", "xnba: configuration file was not created for [$_] because the node is not on the same network as this server");
|
||||
delete $preparednodes{$_};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@args = ($::XNBA_request->{arg});
|
||||
@nodes = keys %preparednodes;
|
||||
}
|
||||
|
||||
my $str_node = join(" ", @nodes);
|
||||
xCAT::MsgUtils->trace(0, "d", "xnba: nodes are $str_node") if ($str_node);
|
||||
|
||||
# Return directly if no nodes in the same network, need to report error on console if its managed nodes are not handled.
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: xnba netboot: no valid nodes. Stop the operation on this server.");
|
||||
|
||||
# If non-shared tftproot and non disjoint mode, need to figure out if no nodes here is a normal case.
|
||||
if ($::XNBA_request->{'_disparatetftp'}->[0] && $::XNBA_request->{'_disjointmode'}->[0] != 1) {
|
||||
# Find out which nodes are really mine only when not sharedtftp and not disjoint mode.
|
||||
my %iphash = ();
|
||||
# flag the IPs or names in iphash
|
||||
foreach (@hostinfo) { $iphash{$_} = 1; }
|
||||
|
||||
# Get managed node list under current server
|
||||
# The node will be under under 'site.master' if no 'noderes.servicenode' is defined
|
||||
my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN");
|
||||
my $req2manage = 0;
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
$req2manage = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($req2manage == 0) {
|
||||
#No nodes are required to be handled, quit without error.
|
||||
return;
|
||||
}
|
||||
}
|
||||
# Okay, now report error as no nodes are handled.
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed to generate xnba configurations for some node(s) on $::myxcatname. Check xCAT log file for more details.";
|
||||
$::XNBA_callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
#now run the begin part of the prescripts
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') {
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact') {
|
||||
$errored = 0;
|
||||
if ($::XNBA_request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: the call is distrubuted to the service node already, so only need to handles my own children");
|
||||
@ -515,7 +594,7 @@ sub process_request {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: nodeset did not distribute to the service node");
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue runbeginpre request");
|
||||
$sub_req->({ command => ['runbeginpre'],
|
||||
node => \@rnodes,
|
||||
node => \@nodes,
|
||||
arg => [ $args[0] ] }, \&pass_along);
|
||||
}
|
||||
if ($errored) {
|
||||
@ -547,7 +626,7 @@ sub process_request {
|
||||
if (!$inittime) { $inittime = 0; }
|
||||
|
||||
my %bphash;
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') {
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact') {
|
||||
$errored = 0;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue setdestiny request");
|
||||
$sub_req->({ command => ['setdestiny'],
|
||||
@ -562,6 +641,7 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: starting to handle configuration...");
|
||||
#Time to actually configure the nodes, first extract database data with the scalable calls
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories
|
||||
@ -589,10 +669,7 @@ sub process_request {
|
||||
mkpath($tftpdir . "/xcat/xnba/nodes/");
|
||||
my %response;
|
||||
$response{node}->[0]->{name}->[0] = $_;
|
||||
if ($args[0] eq 'stat') {
|
||||
$response{node}->[0]->{data}->[0] = getstate($_, $tftpdir);
|
||||
$::XNBA_callback->(\%response);
|
||||
} elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate
|
||||
if ($args[0]) { # Send it on to the destiny plugin, then setstate
|
||||
my $rc;
|
||||
my $errstr;
|
||||
my $ent = $typehash->{$_}->[0];
|
||||
@ -617,45 +694,38 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
}
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: Finish to handle configurations");
|
||||
|
||||
# for offline operation, remove the dhcp entries
|
||||
if ($args[0] eq 'offline') {
|
||||
$sub_req->({ command => ['makedhcp'], arg => ['-d'], node => \@nodes }, $::XNBA_callback);
|
||||
}
|
||||
|
||||
|
||||
#dhcp stuff -- inittime is set when xcatd on sn is started
|
||||
unless (($args[0] eq 'stat') || ($inittime) || ($args[0] eq 'offline')) {
|
||||
unless (($inittime) || ($args[0] eq 'offline')) {
|
||||
my $do_dhcpsetup = 1;
|
||||
|
||||
#my $sitetab = xCAT::Table->new('site');
|
||||
#if ($sitetab) {
|
||||
#(my $ref) = $sitetab->getAttribs({key => 'dhcpsetup'}, 'value');
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("dhcpsetup");
|
||||
my $t_entry = $entries[0];
|
||||
if (defined($t_entry)) {
|
||||
if ($t_entry =~ /0|n|N/) { $do_dhcpsetup = 0; }
|
||||
}
|
||||
|
||||
#}
|
||||
|
||||
if ($do_dhcpsetup) {
|
||||
if ($::XNBA_request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'], arg => ['-l'],
|
||||
node => \@nodes }, $::XNBA_callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
node => \@nodes }, $::XNBA_callback);
|
||||
}
|
||||
my @parameter;
|
||||
push @parameter, '-l' if ($::request->{'_disparatetftp'}->[0]);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue makedhcp request");
|
||||
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
arg => \@parameter,
|
||||
node => \@nodes }, $::XNBA_callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: dhcpsetup=$do_dhcpsetup");
|
||||
}
|
||||
}
|
||||
|
||||
#now run the end part of the prescripts
|
||||
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact')
|
||||
unless ($args[0] eq '') { # or $args[0] eq 'enact')
|
||||
$errored = 0;
|
||||
if ($::XNBA_request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children
|
||||
if ($::XNBA_request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handle my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue runendpre request");
|
||||
$sub_req->({ command => ['runendpre'],
|
||||
node => \@nodes,
|
||||
@ -663,7 +733,7 @@ sub process_request {
|
||||
} else { #nodeset did not distribute to the service node, here we need to let runednpre to distribute the nodes to their masters
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue runendpre request");
|
||||
$sub_req->({ command => ['runendpre'],
|
||||
node => \@rnodes,
|
||||
node => \@nodes,
|
||||
arg => [ $args[0] ] }, \&pass_along);
|
||||
}
|
||||
if ($errored) {
|
||||
@ -674,6 +744,15 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
|
||||
# Return error codes if there are failed nodes
|
||||
if (%failurenodes) {
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed to generate xnba configurations for some node(s) on $::myxcatname. Check xCAT log file for more details.";
|
||||
$::XNBA_callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user