mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-06-12 08:10:12 +00:00
1, use 'disjointdhcps' for nodeset disjoint mode
2, handle 'disjoint' in preprocess method, to make sure that no request will be sent to SN which does not manage the nodes. 3, refine 'stat' to make sure it could query unmanaged nodes on-demand.
This commit is contained in:
@ -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)
|
||||
@ -298,10 +299,6 @@ site Attributes:
|
||||
If value is set to a hostname, the directory in tftpdir
|
||||
will be mounted from that hostname on the SN
|
||||
|
||||
disjointnetboot: Only avaialbe when sharedtftp is set to 0/no. If set to '1', a service node
|
||||
handles the netboot (petitboot/grub2/xnba) config file only for the nodes it manages.
|
||||
The default value is '0'. '0' means handle all the nodes in the same subnet.
|
||||
|
||||
sharedinstall: Indicates if a shared file system will be used for installation
|
||||
resources. Possible values are: 'no', 'sns', or 'all'. 'no'
|
||||
means a shared file system is not being used. 'sns' means a
|
||||
|
@ -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" .
|
||||
@ -1171,9 +1172,6 @@ passed as argument rather than by table value',
|
||||
" in tftpdir is mounted on all on Service Nodes. Default is 1/yes.\n" .
|
||||
" If value is set to a hostname, the directory in tftpdir\n" .
|
||||
" will be mounted from that hostname on the SN\n\n" .
|
||||
" disjointnetboot: Only available when sharedtftp is set to 0/no. If set to '1', a service node\n" .
|
||||
" handles the netboot (petitboot/grub2/xnba) config file only for the nodes it manages.\n" .
|
||||
" The default value is '0'. '0' means handle all the nodes in the same subnet.\n\n" .
|
||||
" sharedinstall: Indicates if a shared file system will be used for installation\n" .
|
||||
" resources. Possible values are: 'no', 'sns', or 'all'. 'no' \n" .
|
||||
" means a shared file system is not being used. 'sns' means a\n" .
|
||||
|
@ -1,5 +1,6 @@
|
||||
package xCAT::Scope;
|
||||
|
||||
#use Data::Dumper;
|
||||
use xCAT::Utils;
|
||||
use xCAT::Table;
|
||||
use xCAT::ServiceNodeUtils qw(getSNList);
|
||||
@ -129,12 +130,12 @@ sub get_parallel_scope {
|
||||
|
||||
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
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -146,18 +147,19 @@ sub get_broadcast_scope_with_parallel {
|
||||
#Exit if the packet has been preprocessed in its history
|
||||
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
||||
|
||||
my $snlist = shift;
|
||||
#Handle the one for current management/service node
|
||||
my $reqs = get_parallel_scope($req);
|
||||
my @requests = @$reqs;
|
||||
|
||||
#Broadcast the request to other management/service nodes
|
||||
foreach (xCAT::ServiceNodeUtils->getSNList()) {
|
||||
if (xCAT::NetworkUtils->thishostisnot($_)) {
|
||||
my $xcatdest = $_;
|
||||
foreach (@$snlist) {
|
||||
my $xcatdest = $_;
|
||||
if (xCAT::NetworkUtils->thishostisnot($xcatdest)) {
|
||||
my $reqcopy = {%$req};
|
||||
$reqcopy->{'_xcatdest'} = $_;
|
||||
$reqcopy->{'_xcatdest'} = $xcatdest;
|
||||
$reqcopy->{_xcatpreprocessed}->[0] = 1;
|
||||
#Apply callback to filter the node range in future.
|
||||
|
||||
$reqs = get_parallel_scope($reqcopy);
|
||||
foreach (@$reqs) {
|
||||
push @requests, {%$_};
|
||||
@ -167,6 +169,59 @@ sub get_broadcast_scope_with_parallel {
|
||||
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. (Work under disjoint mode)
|
||||
|
||||
Arguments:
|
||||
Reference of request
|
||||
SN hash: Hash of target service nodes => Managed CNs
|
||||
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]; }
|
||||
|
||||
my $sn_hash = shift;
|
||||
my @reqs = ();
|
||||
#Handle the one for current management/service node
|
||||
if ( xCAT::Utils->isMN() ) {
|
||||
$reqs = get_parallel_scope($req);
|
||||
}
|
||||
my @requests = @$reqs;
|
||||
|
||||
#Broadcast the request to other management/service nodes
|
||||
foreach (keys %$sn_hash) {
|
||||
my $xcatdest = $_;
|
||||
if (xCAT::NetworkUtils->thishostisnot($xcatdest)) {
|
||||
my $reqcopy = {%$req};
|
||||
$reqcopy->{'_xcatdest'} = $xcatdest;
|
||||
$reqcopy->{'node'} = $sn_hash->{$xcatdest};
|
||||
$reqcopy->{_xcatpreprocessed}->[0] = 1;
|
||||
|
||||
$reqs = get_parallel_scope($reqcopy);
|
||||
foreach (@$reqs) {
|
||||
push @requests, {%$_};
|
||||
}
|
||||
}
|
||||
}
|
||||
#print Dumper(\@requests);
|
||||
return \@requests;
|
||||
}
|
||||
|
||||
|
||||
sub get_broadcast_scope {
|
||||
my $req = shift;
|
||||
|
@ -481,7 +481,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>
|
||||
|
||||
|
@ -174,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]);
|
||||
@ -184,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")) {
|
||||
@ -292,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);
|
||||
}
|
||||
@ -332,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,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;
|
||||
@ -400,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}) {
|
||||
@ -467,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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,8 +478,28 @@ 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");
|
||||
return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash);
|
||||
}
|
||||
}
|
||||
# Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs.
|
||||
@ -495,19 +513,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});
|
||||
@ -515,6 +530,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 {
|
||||
@ -527,104 +546,101 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
$::myxcatname = $hostinfo[-1];
|
||||
xCAT::MsgUtils->trace(0, "d", "grub2: running on $::myxcatname");
|
||||
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 {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $node;
|
||||
$response{node}->[0]->{data}->[0] = getstate($node, $tftpdir);
|
||||
$callback->(\%response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
my @unmanagednodes = ();
|
||||
#if not shared tftpdir, then broadcast, otherwise, set up everything
|
||||
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: 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
|
||||
@nodes = ();
|
||||
|
||||
my %iphash = ();
|
||||
# flag the IPs or names in iphash
|
||||
foreach (@hostinfo) { $iphash{$_} = 1; }
|
||||
#print Dumper(\%iphash);
|
||||
|
||||
my $mynodeonly = 0;
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("disjointnetboot");
|
||||
my $t_entry = $entries[0];
|
||||
if (defined($t_entry)) {
|
||||
$mynodeonly = $t_entry;
|
||||
}
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: disjointnetboot=$mynodeonly");
|
||||
|
||||
# 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");
|
||||
#print Dumper($sn_hash);
|
||||
my %managed = ();
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
my $cur_xmaster = $_;
|
||||
foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
my $notsamenet_nodes_err = '';
|
||||
my $notsamenet_nodes_warn = '';
|
||||
|
||||
foreach (@rnodes) {
|
||||
# For MN, the scope is all CN, for SN, the scope is the nodes it managed if disjointnetboot is set.
|
||||
my $req2manage = exists($managed{$_});
|
||||
if ($req2manage) {
|
||||
push @unmanagednodes, $_;
|
||||
# quick pass through if disjoint is set.
|
||||
next if ( $mynodeonly == 1 && xCAT::Utils->isMN() != 1 );
|
||||
}
|
||||
|
||||
# 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($_)) {
|
||||
if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) {
|
||||
push @nodes, $_;
|
||||
} elsif ( $req2manage ) {
|
||||
# report error when it is under my control but I cannot handle it.
|
||||
$notsamenet_nodes_err .= " $_";
|
||||
}
|
||||
else {
|
||||
$notsamenet_nodes_warn .= " $_";
|
||||
}
|
||||
}
|
||||
|
||||
if ( $mynodeonly == 1 && scalar (@unmanagednodes) > 0 && xCAT::Utils->isMN() != 1) {
|
||||
my $str_umnodes = join(" ", @unmanagednodes);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: unmanaged nodes are $str_umnodes");
|
||||
}
|
||||
|
||||
if ( $notsamenet_nodes_err || $notsamenet_nodes_warn ) {
|
||||
my $msg = "grub2 configuration file was not created ";
|
||||
$msg .= "on $::myxcatname " if ( $::myxcatname );
|
||||
$msg .= "for below nodes because sharedtftp attribute is not set and the nodes are not on same network as this xcatmaster: ";
|
||||
xCAT::MsgUtils->message("S", $msg . $notsamenet_nodes_warn . $notsamenet_nodes_err);
|
||||
# For managed children, need to report error
|
||||
if ( $notsamenet_nodes_err ) {
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = $msg . $notsamenet_nodes_err;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
} 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 {
|
||||
@nodes = @rnodes;
|
||||
@nodes = keys %preparednodes;
|
||||
}
|
||||
|
||||
#>>>>>>>used for trace log>>>>>>>
|
||||
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
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: grub2 netboot: no valid nodes. Stop the operation on this server.");
|
||||
|
||||
# It must be an error if my managed nodes are not handled.
|
||||
if (xCAT::Utils->isMN() != 1 && $request->{'_disparatetftp'}->[0] && $request->{'_disjointmode'}->[0] != 1) {
|
||||
# Find out which nodes are really mine only when not sharedtftp and not disjoint mode.
|
||||
# For other case, all passing node range are required to be handled.
|
||||
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 %managed = ();
|
||||
my $req2manage = 0;
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
#my $cur_xmaster = $_;
|
||||
#foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
$req2manage = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
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.\n";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref($request->{arg})) {
|
||||
@args = @{ $request->{arg} };
|
||||
} else {
|
||||
@args = ($request->{arg});
|
||||
}
|
||||
|
||||
#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 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");
|
||||
@ -654,7 +670,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'],
|
||||
@ -669,6 +685,7 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@ -694,10 +711,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;
|
||||
@ -713,11 +727,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) {
|
||||
|
||||
@ -738,7 +752,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
|
||||
@ -838,7 +852,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");
|
||||
@ -859,6 +873,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.\n";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
@ -79,7 +79,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
|
||||
|
||||
@ -169,18 +169,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,
|
||||
@ -216,18 +217,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;
|
||||
}
|
||||
|
||||
@ -236,9 +232,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;
|
||||
}
|
||||
@ -282,12 +278,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}) {
|
||||
@ -333,6 +331,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
|
||||
@ -345,21 +350,43 @@ 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");
|
||||
return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash);
|
||||
}
|
||||
}
|
||||
# Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs.
|
||||
@ -374,16 +401,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 +421,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,104 +437,101 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
$::myxcatname = $hostinfo[-1];
|
||||
xCAT::MsgUtils->trace(0, "d", "petitboot: running on $::myxcatname");
|
||||
|
||||
my @unmanagednodes = ();
|
||||
#if not shared tftpdir, then broadcast, otherwise, set up everything
|
||||
if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
@nodes = ();
|
||||
|
||||
my %iphash = ();
|
||||
# flag the IPs or names in iphash
|
||||
foreach (@hostinfo) { $iphash{$_} = 1; }
|
||||
#print Dumper(\%iphash);
|
||||
|
||||
my $mynodeonly = 0;
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("disjointnetboot");
|
||||
my $t_entry = $entries[0];
|
||||
if (defined($t_entry)) {
|
||||
$mynodeonly = $t_entry;
|
||||
}
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: disjointnetboot=$mynodeonly");
|
||||
|
||||
# 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");
|
||||
#print Dumper($sn_hash);
|
||||
my %managed = ();
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
my $cur_xmaster = $_;
|
||||
foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
last;
|
||||
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 {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $node;
|
||||
$response{node}->[0]->{data}->[0] = getstate($node, $tftpdir);
|
||||
$callback->(\%response);
|
||||
}
|
||||
|
||||
my $notsamenet_nodes_err = '';
|
||||
my $notsamenet_nodes_warn = '';
|
||||
|
||||
foreach (@rnodes) {
|
||||
# For MN, the scope is all CN, for SN, the scope is the nodes it managed if disjointnetboot is set.
|
||||
my $req2manage = exists($managed{$_});
|
||||
if ($req2manage) {
|
||||
push @unmanagednodes, $_;
|
||||
# quick pass through if disjoint is set.
|
||||
next if ( $mynodeonly == 1 && xCAT::Utils->isMN() != 1 );
|
||||
}
|
||||
|
||||
# Only handle its boot configuration files if the node in same subnet
|
||||
if (xCAT::NetworkUtils->nodeonmynet($_)) {
|
||||
push @nodes, $_;
|
||||
} elsif ( $req2manage ) {
|
||||
# report error when it is under my control but I cannot handle it.
|
||||
$notsamenet_nodes_err .= " $_";
|
||||
}
|
||||
else {
|
||||
$notsamenet_nodes_warn .= " $_";
|
||||
}
|
||||
}
|
||||
|
||||
if ( $mynodeonly == 1 && scalar (@unmanagednodes) > 0 && xCAT::Utils->isMN() != 1) {
|
||||
my $str_umnodes = join(" ", @unmanagednodes);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: unmanaged nodes are $str_umnodes");
|
||||
}
|
||||
|
||||
if ( $notsamenet_nodes_err || $notsamenet_nodes_warn ) {
|
||||
my $msg = "petitboot configuration file was not created ";
|
||||
$msg .= "on $::myxcatname " if ( $::myxcatname );
|
||||
$msg .= "for below nodes because sharedtftp attribute is not set and the nodes are not on same network as this xcatmaster: ";
|
||||
xCAT::MsgUtils->message("S", $msg . $notsamenet_nodes_warn . $notsamenet_nodes_err);
|
||||
# For managed children, need to report error
|
||||
if ( $notsamenet_nodes_err ) {
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = $msg . $notsamenet_nodes_err;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@nodes = @rnodes;
|
||||
}
|
||||
|
||||
#>>>>>>>used for trace log>>>>>>>
|
||||
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
|
||||
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: 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
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: no valid nodes. Stop the operation on this server.");
|
||||
|
||||
# It must be an error if my managed nodes are not handled.
|
||||
if (xCAT::Utils->isMN() != 1 && $request->{'_disparatetftp'}->[0] && $request->{'_disjointmode'}->[0] != 1) {
|
||||
# Find out which nodes are really mine only when not sharedtftp and not disjoint mode.
|
||||
# For other case, all passing node range are required to be handled.
|
||||
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 %managed = ();
|
||||
my $req2manage = 0;
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
#my $cur_xmaster = $_;
|
||||
#foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
$req2manage = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($req2manage == 0) {
|
||||
xCAT::MsgUtils->trace(0, "d", "petitboot: No nodes are required to be managed on this server");
|
||||
return;
|
||||
}
|
||||
}
|
||||
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.\n";
|
||||
$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 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");
|
||||
@ -517,7 +543,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) {
|
||||
@ -535,7 +561,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'],
|
||||
@ -561,6 +587,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);
|
||||
@ -584,13 +612,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);
|
||||
@ -601,11 +626,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) {
|
||||
|
||||
@ -616,7 +640,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;
|
||||
@ -626,16 +650,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') {
|
||||
@ -645,7 +670,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");
|
||||
@ -655,7 +680,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) {
|
||||
@ -666,6 +691,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.\n";
|
||||
$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,7 +417,27 @@ 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");
|
||||
return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash);
|
||||
}
|
||||
}
|
||||
# Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs.
|
||||
@ -438,12 +467,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] } });
|
||||
@ -451,104 +482,101 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
|
||||
my @hostinfo = xCAT::NetworkUtils->determinehostname();
|
||||
$::myxcatname = $hostinfo[-1];
|
||||
xCAT::MsgUtils->trace(0, "d", "xnba: running on $::myxcatname");
|
||||
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 {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
$response{node}->[0]->{name}->[0] = $node;
|
||||
$response{node}->[0]->{data}->[0] = getstate($node, $tftpdir);
|
||||
$::XNBA_callback->(\%response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
my @unmanagednodes = ();
|
||||
#if not shared tftpdir, then broadcast, otherwise, set up everything
|
||||
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: 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
|
||||
@nodes = ();
|
||||
|
||||
my %iphash = ();
|
||||
# flag the IPs or names in iphash
|
||||
foreach (@hostinfo) { $iphash{$_} = 1; }
|
||||
#print Dumper(\%iphash);
|
||||
|
||||
my $mynodeonly = 0;
|
||||
my @entries = xCAT::TableUtils->get_site_attribute("disjointnetboot");
|
||||
my $t_entry = $entries[0];
|
||||
if (defined($t_entry)) {
|
||||
$mynodeonly = $t_entry;
|
||||
}
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: disjointnetboot=$mynodeonly");
|
||||
|
||||
# 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");
|
||||
#print Dumper($sn_hash);
|
||||
my %managed = ();
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
my $cur_xmaster = $_;
|
||||
foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
my $notsamenet_nodes_err = '';
|
||||
my $notsamenet_nodes_warn = '';
|
||||
|
||||
foreach (@rnodes) {
|
||||
# For MN, the scope is all CN, for SN, the scope is the nodes it managed if disjointnetboot is set.
|
||||
my $req2manage = exists($managed{$_});
|
||||
if ($req2manage) {
|
||||
push @unmanagednodes, $_;
|
||||
# quick pass through if disjoint is set.
|
||||
next if ( $mynodeonly == 1 && xCAT::Utils->isMN() != 1 );
|
||||
}
|
||||
|
||||
# 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($_)) {
|
||||
if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) {
|
||||
push @nodes, $_;
|
||||
} elsif ( $req2manage ) {
|
||||
# report error when it is under my control but I cannot handle it.
|
||||
$notsamenet_nodes_err .= " $_";
|
||||
}
|
||||
else {
|
||||
$notsamenet_nodes_warn .= " $_";
|
||||
}
|
||||
}
|
||||
|
||||
if ( $mynodeonly == 1 && scalar (@unmanagednodes) > 0 && xCAT::Utils->isMN() != 1) {
|
||||
my $str_umnodes = join(" ", @unmanagednodes);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: unmanaged nodes are $str_umnodes");
|
||||
}
|
||||
|
||||
if ( $notsamenet_nodes_err || $notsamenet_nodes_warn ) {
|
||||
my $msg = "xnba configuration file was not created ";
|
||||
$msg .= "on $::myxcatname " if ( $::myxcatname );
|
||||
$msg .= "for below nodes because sharedtftp attribute is not set and the nodes are not on same network as this xcatmaster: ";
|
||||
xCAT::MsgUtils->message("S", $msg . $notsamenet_nodes_warn . $notsamenet_nodes_err);
|
||||
# For managed children, need to report error
|
||||
if ( $notsamenet_nodes_err ) {
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = $msg . $notsamenet_nodes_err;
|
||||
xCAT::MsgUtils->message("E", $rsp, $::XNBA_callback);
|
||||
} 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 {
|
||||
@nodes = @rnodes;
|
||||
@nodes = keys %preparednodes;
|
||||
}
|
||||
|
||||
#>>>>>>>used for trace log>>>>>>>
|
||||
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
|
||||
unless (@nodes) {
|
||||
xCAT::MsgUtils->message("S", "xCAT: xnba netboot: no valid nodes. Stop the operation on this server.");
|
||||
|
||||
# It must be an error if my managed nodes are not handled.
|
||||
if (xCAT::Utils->isMN() != 1 && $::XNBA_request->{'_disparatetftp'}->[0] && $::XNBA_request->{'_disjointmode'}->[0] != 1) {
|
||||
# Find out which nodes are really mine only when not sharedtftp and not disjoint mode.
|
||||
# For other case, all passing node range are required to be handled.
|
||||
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 %managed = ();
|
||||
my $req2manage = 0;
|
||||
foreach (keys %$sn_hash) {
|
||||
if (exists($iphash{$_})) {
|
||||
#my $cur_xmaster = $_;
|
||||
#foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; }
|
||||
$req2manage = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($req2manage == 0) {
|
||||
xCAT::MsgUtils->trace(0, "d", "xnba: No nodes are required to be managed on this server");
|
||||
return;
|
||||
}
|
||||
}
|
||||
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.\n";
|
||||
$::XNBA_callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref($::XNBA_request->{arg})) {
|
||||
@args = @{ $::XNBA_request->{arg} };
|
||||
} else {
|
||||
@args = ($::XNBA_request->{arg});
|
||||
}
|
||||
|
||||
#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");
|
||||
@ -560,7 +588,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) {
|
||||
@ -592,7 +620,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'],
|
||||
@ -607,6 +635,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
|
||||
@ -634,10 +663,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];
|
||||
@ -662,43 +688,36 @@ 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 handle my own children
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue runendpre request");
|
||||
@ -708,7 +727,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) {
|
||||
@ -719,6 +738,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.\n";
|
||||
$::XNBA_callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user