mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-06-24 15:05:36 +00:00
make xnba plugin error hanlding better for batch operation
This commit is contained in:
@ -185,10 +185,24 @@ sub setstate {
|
||||
$pxelinuxkcmdline =~ s/!myipfn!/$ipfn/g;
|
||||
}
|
||||
}
|
||||
my $pcfg;
|
||||
unlink($tftpdir . "/xcat/xnba/nodes/" . $node . ".pxelinux");
|
||||
open($pcfg, '>', $tftpdir . "/xcat/xnba/nodes/" . $node);
|
||||
|
||||
my $bootloader_root = "$tftpdir/xcat/xnba/nodes";
|
||||
unless (-d "$bootloader_root") {
|
||||
mkpath("$bootloader_root");
|
||||
}
|
||||
|
||||
my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']);
|
||||
if ($cref and $cref->{currstate} eq "offline") {
|
||||
unlink("$bootloader_root/$node");
|
||||
unlink("$bootloader_root/$node.pxelinux");
|
||||
unlink("$bootloader_root/$node.uefi");
|
||||
unlink("$bootloader_root/$node.elilo");
|
||||
return (0, "");
|
||||
}
|
||||
|
||||
my $pcfg;
|
||||
unlink("$bootloader_root/$node.pxelinux");
|
||||
open($pcfg, '>', "$bootloader_root/$node");
|
||||
print $pcfg "#!gpxe\n";
|
||||
if ($cref->{currstate}) {
|
||||
print $pcfg "#" . $cref->{currstate} . "\n";
|
||||
@ -284,30 +298,48 @@ sub setstate {
|
||||
print $pcfg "LOCALBOOT 0\n";
|
||||
close($pcfg);
|
||||
}
|
||||
return (0, "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
my $errored = 0;
|
||||
|
||||
my %failurenodes;
|
||||
sub pass_along {
|
||||
my $resp = shift;
|
||||
return unless ($resp);
|
||||
|
||||
if ($resp->{error} and not ref $resp->{error}) {
|
||||
$resp->{error} = [ $resp->{error} ];
|
||||
}
|
||||
if ($resp and ($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) {
|
||||
$errored = 1;
|
||||
|
||||
my $failure = 0;
|
||||
if ($resp->{errorabort}) { # Global error, it normally means to stop the parent execution. For example, DB operation error.
|
||||
$failure = 2;
|
||||
delete $resp->{errorabort};
|
||||
} elsif (($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) {
|
||||
$failure = 1;
|
||||
}
|
||||
|
||||
foreach (@{ $resp->{node} }) {
|
||||
if ($_->{error} or $_->{errorcode}) {
|
||||
$errored = 1;
|
||||
}
|
||||
if ($_->{_addkcmdlinehandled}) {
|
||||
$::XNBA_addkcmdlinehandled->{ $_->{name}->[0] } = 1;
|
||||
return; #Don't send back to client this internal hint
|
||||
}
|
||||
|
||||
if ($_->{error} or $_->{errorcode}) {
|
||||
$failure = 1 unless ($failure); # keep its value if $failure is 2
|
||||
if ($_->{name}) {
|
||||
$failurenodes{$_->{name}->[0]} = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
$::XNBA_callback->($resp);
|
||||
|
||||
# Set the module scope error flag.
|
||||
if ( $failure ) {
|
||||
$errored = $failure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -406,7 +438,7 @@ sub preprocess_request {
|
||||
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";
|
||||
"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;
|
||||
}
|
||||
@ -458,8 +490,8 @@ sub process_request {
|
||||
my $sub_req = shift;
|
||||
undef $::XNBA_addkcmdlinehandled; # clear out any previous value
|
||||
my @args;
|
||||
my @nodes;
|
||||
my @rnodes;
|
||||
undef %failurenodes;
|
||||
|
||||
#>>>>>>>used for trace log start>>>>>>>
|
||||
my %opt;
|
||||
@ -510,7 +542,6 @@ sub process_request {
|
||||
|
||||
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($_);
|
||||
@ -597,10 +628,8 @@ sub process_request {
|
||||
arg => [ $args[0] ] }, \&pass_along);
|
||||
}
|
||||
if ($errored) {
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed in running begin prescripts. Processing will still continue.\n";
|
||||
$::XNBA_callback->($rsp);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: Failed in running begin prescripts.");
|
||||
return if ($errored > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,8 +664,8 @@ sub process_request {
|
||||
bootparams => \%bphash},
|
||||
\&pass_along);
|
||||
if ($errored) {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: Failed in processing setdestiny. Processing will not continue.");
|
||||
return;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: Failed in processing setdestiny.");
|
||||
return if ($errored > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -644,11 +673,11 @@ sub process_request {
|
||||
#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
|
||||
my $mactab = xCAT::Table->new('mac'); #to get all the hostnames
|
||||
my %nrhash = %{ $noderestab->getNodesAttribs(\@nodes, [qw(tftpdir)]) };
|
||||
my %chainhash = %{ $chaintab->getNodesAttribs(\@nodes, [qw(currstate)]) };
|
||||
my %iscsihash;
|
||||
my $iscsitab = xCAT::Table->new('iscsi');
|
||||
my %machash = ();
|
||||
|
||||
if ($iscsitab) {
|
||||
%iscsihash = %{ $iscsitab->getNodesAttribs(\@nodes, [qw(server target)]) };
|
||||
@ -657,15 +686,15 @@ sub process_request {
|
||||
my $typehash = $typetab->getNodesAttribs(\@nodes, ['provmethod']);
|
||||
my $linuximgtab = xCAT::Table->new('linuximage', -create => 1);
|
||||
|
||||
my %machash = %{ $mactab->getNodesAttribs(\@nodes, [qw(mac)]) };
|
||||
my @normalnodeset = ();
|
||||
foreach (@nodes) {
|
||||
my $tftpdir;
|
||||
next if (exists($failurenodes{$_}));
|
||||
|
||||
my $tftpdir = $globaltftpdir;
|
||||
if ($nrhash{$_}->[0] and $nrhash{$_}->[0]->{tftpdir}) {
|
||||
$tftpdir = $nrhash{$_}->[0]->{tftpdir};
|
||||
} else {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
mkpath($tftpdir . "/xcat/xnba/nodes/");
|
||||
|
||||
my %response;
|
||||
$response{node}->[0]->{name}->[0] = $_;
|
||||
if ($args[0]) { # Send it on to the destiny plugin, then setstate
|
||||
@ -678,18 +707,13 @@ sub process_request {
|
||||
$linuximghash = $linuximgtab->getAttribs({ imagename => $osimgname }, 'boottarget', 'addkcmdline');
|
||||
}
|
||||
($rc, $errstr) = setstate($_, \%bphash, \%chainhash, \%machash, \%iscsihash, $tftpdir, $linuximghash);
|
||||
|
||||
#currently, it seems setstate doesn't return error codes...
|
||||
#if ($rc) {
|
||||
# $response{node}->[0]->{errorcode}->[0]= $rc;
|
||||
# $response{node}->[0]->{errorc}->[0]= $errstr;
|
||||
# $::XNBA_callback->(\%response);
|
||||
#}
|
||||
if ($args[0] eq 'offline') {
|
||||
unlink($tftpdir . "/xcat/xnba/nodes/" . $_);
|
||||
unlink($tftpdir . "/xcat/xnba/nodes/" . $_ . ".pxelinux");
|
||||
unlink($tftpdir . "/xcat/xnba/nodes/" . $_ . ".uefi");
|
||||
unlink($tftpdir . "/xcat/xnba/nodes/" . $_ . ".elilo");
|
||||
if ($rc) {
|
||||
$response{node}->[0]->{errorcode}->[0] = $rc;
|
||||
$response{node}->[0]->{errorc}->[0] = $errstr;
|
||||
$failurenodes{$_} = 1;
|
||||
$::XNBA_callback->(\%response);
|
||||
} else {
|
||||
push @normalnodeset, $_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -712,7 +736,7 @@ sub process_request {
|
||||
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
arg => \@parameter,
|
||||
node => \@nodes }, $::XNBA_callback);
|
||||
node => \@normalnodeset }, $::XNBA_callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: dhcpsetup=$do_dhcpsetup");
|
||||
}
|
||||
@ -724,19 +748,16 @@ sub process_request {
|
||||
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,
|
||||
node => \@normalnodeset,
|
||||
arg => [ $args[0], '-l' ] }, \&pass_along);
|
||||
} 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 => \@nodes,
|
||||
node => \@normalnodeset,
|
||||
arg => [ $args[0] ] }, \&pass_along);
|
||||
}
|
||||
if ($errored) {
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed in running end prescripts. Processing will still continue.\n";
|
||||
$::XNBA_callback->($rsp);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: Failed in running end prescripts.");
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user