2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-07-23 12:51:10 +00:00

Not return directly for nodeset when hit one node failure

This commit is contained in:
Bin Xu
2017-09-19 07:46:02 +08:00
parent 1f50bf6714
commit e5d8857054
3 changed files with 303 additions and 208 deletions

View File

@@ -355,9 +355,11 @@ sub mknetboot
$img_hash{$imagename}->{'partfile'} = $ref1->{'partitionfile'};
}
} else {
$callback->(
{ error => ["The os image $imagename does not exists on the osimage table for $node"],
errorcode => [1] });
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = "The OS image '$imagename' for node does not exist";
$callback->($rsp);
next;
}
}
@@ -379,6 +381,7 @@ sub mknetboot
$cfgpart = $ph->{'cfgpart'};
}
else {
# This is deprecated mode to define node's provmethod, not supported now.
$osver = $ent->{os};
$arch = $ent->{arch};
$profile = $ent->{profile};
@@ -402,10 +405,12 @@ sub mknetboot
$rootfstype = $ref1->{'rootfstype'};
}
} else {
$callback->(
{ error => [qq{Cannot find the linux image called "$osver-$arch-$imgname-$profile", maybe you need to use the "nodeset <nr> osimage=<osimage name>" command to set the boot state}],
errorcode => [1] }
);
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = "The OS image $osver-$arch-$imgname-$profile for node does not exist";
$callback->($rsp);
next;
}
if (!$linuximagetab) {
@@ -441,22 +446,23 @@ sub mknetboot
}
}
} else {
$callback->(
{ error => [qq{ Cannot find the linux image called "$osver-$arch-$imgname-$profile", maybe you need to use the "nodeset <nr> osimage=<your_image_name>" command to set the boot state}],
errorcode => [1] }
);
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = "The OS image $osver-$arch-$imgname-$profile for node does not exist";
$callback->($rsp);
next;
}
}
#print"osvr=$osver, arch=$arch, profile=$profile, imgdir=$rootimgdir\n";
unless ($osver and $arch and $profile)
{
$callback->(
{
error => ["Insufficient nodetype entry or osimage entry for $node"],
errorcode => [1]
}
);
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = "Insufficient nodetype entry or osimage entry for $node";
$callback->($rsp);
next;
}
@@ -467,18 +473,20 @@ sub mknetboot
# statelite images are not packed.
if ($statelite) {
unless (-r "$rootimgdir/kernel") {
$callback->({
error => [qq{Did you run "genimage" before running "liteimg"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode => [1]
});
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = qq{Did you run "genimage" before running "liteimg"? kernel cannot be found at $rootimgdir/kernel on $myname};
$callback->($rsp);
next;
}
if (!-r "$rootimgdir/initrd-statelite.gz") {
if (!-r "$rootimgdir/initrd.gz") {
$callback->({
error => [qq{Did you run "genimage" before running "liteimg"? initrd.gz or initrd-statelite.gz cannot be found at $rootimgdir/initrd.gz on $myname}],
errorcode => [1]
});
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = qq{Did you run "genimage" before running "liteimg"? initrd.gz or initrd-statelite.gz cannot be found at $rootimgdir/initrd.gz on $myname};
$callback->($rsp);
next;
}
else {
@@ -486,35 +494,40 @@ sub mknetboot
}
}
if ($rootfstype eq "ramdisk" and !-r "$rootimgdir/rootimg-statelite.gz") {
$callback->({
error => [qq{No packed image for platform $osver, architecture $arch and profile $profile, please run "liteimg" to create it.}],
errorcode => [1]
});
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = qq{No packed image for platform $osver, architecture $arch and profile $profile, please run "liteimg" to create it.};
$callback->($rsp);
next;
}
} else {
unless (-r "$rootimgdir/kernel") {
$callback->({
error => [qq{Did you run "genimage" before running "packimage"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode => [1]
});
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = qq{Did you run "genimage" before running "packimage"? kernel cannot be found at $rootimgdir/kernel on $myname};
$callback->($rsp);
next;
}
if (!-r "$rootimgdir/initrd-stateless.gz") {
if (!-r "$rootimgdir/initrd.gz") {
$callback->({
error => [qq{Did you run "genimage" before running "packimage"? initrd.gz or initrd-stateless.gz cannot be found at $rootimgdir/initrd.gz on $myname}],
errorcode => [1]
});
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = qq{Did you run "genimage" before running "packimage"? initrd.gz or initrd-stateless.gz cannot be found at $rootimgdir/initrd.gz on $myname};
$callback->($rsp);
next;
} else {
copy("$rootimgdir/initrd.gz", "$rootimgdir/initrd-stateless.gz");
}
}
unless ( -f -r "$rootimgdir/$compressedrootimg") {
$callback->({
error => ["No packed image for platform $osver, architecture $arch, and profile $profile found at $rootimgdir/rootimg.gz or $rootimgdir/rootimg.sfs on $myname, please run packimage (e.g. packimage -o $osver -p $profile -a $arch"],
errorcode => [1] });
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = "No packed image for platform $osver, architecture $arch, and profile $profile found at $rootimgdir/rootimg.gz or $rootimgdir/rootimg.sfs on $myname, please run packimage (e.g. packimage -o $osver -p $profile -a $arch";
$callback->($rsp);
next;
}
}
@@ -567,21 +580,21 @@ sub mknetboot
} else {
$initrdloc .= "/initrd-statelite.gz";
}
unless (-r "$tftppath/kernel"
and -r $initrdloc) {
$callback->({
error => [qq{copying to $tftppath failed}],
errorcode => [1]
});
unless (-r "$tftppath/kernel" and -r $initrdloc) {
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = qq{Copying to $tftppath failed.};
$callback->($rsp);
next;
}
} else {
unless (-r "$tftppath/kernel"
and -r "$tftppath/initrd-stateless.gz") {
$callback->({
error => [qq{copying to $tftppath failed}],
errorcode => [1]
});
unless (-r "$tftppath/kernel" and -r "$tftppath/initrd-stateless.gz") {
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = qq{Copying to $tftppath failed.};
$callback->($rsp);
next;
}
}
@@ -635,14 +648,11 @@ sub mknetboot
}
unless ($imgsrv)
{
$callback->(
{
error => [
"Unable to determine or reasonably guess the image server for $node"
],
errorcode => [1]
}
);
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = "Unable to determine or reasonably guess the image server for $node";
$callback->($rsp);
next;
}
my $kcmdline;
@@ -753,11 +763,9 @@ sub mknetboot
}
else {
if (-r "$rootimgdir/$compressedrootimg.metainfo") {
$kcmdline =
"imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/$compressedrootimg.metainfo ";
$kcmdline = "imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/$compressedrootimg.metainfo ";
} else {
$kcmdline =
"imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/$compressedrootimg ";
$kcmdline = "imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/$compressedrootimg ";
}
$kcmdline .= "XCAT=$xcatmaster:$xcatdport ";
$kcmdline .= "NODE=$node ";
@@ -832,14 +840,11 @@ sub mknetboot
#my $sent = $hmtab->getNodeAttribs($node,['serialspeed','serialflow']);
unless ($sent->{serialspeed})
{
$callback->(
{
error => [
"serialport defined, but no serialspeed for $node in nodehm table"
],
errorcode => [1]
}
);
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $node;
$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = "serialport defined, but no serialspeed for $node in nodehm table";
$callback->($rsp);
next;
}
if ($arch =~ /ppc64/i) {

View File

@@ -35,6 +35,7 @@ my $tftpdir = "/tftpboot";
my $nonodestatus = 0;
my %failurenodes = ();
#my $sitetab = xCAT::Table->new('site');
#if ($sitetab) {
@@ -64,36 +65,41 @@ sub process_request {
my $result = xCAT::TableUtils->checkCredFiles($callback);
}
if ($request->{command}->[0] eq 'getdestiny') {
xCAT::MsgUtils->trace(0, "d", "destiny->process_request: starting getdestiny...");
getdestiny(0);
}
if ($request->{command}->[0] eq 'nextdestiny') {
} elsif ($request->{command}->[0] eq 'nextdestiny') {
xCAT::MsgUtils->trace(0, "d", "destiny->process_request: starting nextdestiny...");
nextdestiny(0, 1); #it is called within dodestiny
}
if ($request->{command}->[0] eq 'setdestiny') {
} elsif ($request->{command}->[0] eq 'setdestiny') {
xCAT::MsgUtils->trace(0, "d", "destiny->process_request: starting setdestiny...");
setdestiny($request, 0);
}
xCAT::MsgUtils->trace(0, "d", "destiny->process_request: processing is finished for " . $request->{command}->[0]);
}
sub relay_response {
my $resp = shift;
my $failure = 0;
return unless ($resp);
$callback->($resp);
if ($resp and ($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) {
$failure = 1;
$errored = 2;
return;
}
# quick return when detect failure.
unless ( $failure ) {
foreach (@{ $resp->{node} }) {
if ($_->{error} or $_->{errorcode}) {
$failure = 1;
last;
my $failure = 0;
# Partial error on nodes, it allows to continue the rest of business on the sucessful nodes.
foreach (@{ $resp->{node} }) {
if ($_->{error} or $_->{errorcode}) {
$failure = 1;
if ($_->{name}) {
$failurenodes{$_->{name}->[0]} = 2;
}
}
}
if ( $failure ) {
$errored = $failure;
}
}
sub setdestiny {
@@ -101,7 +107,6 @@ sub setdestiny {
my $flag = shift;
my $noupdate = shift;
$chaintab = xCAT::Table->new('chain', -create => 1);
my @nodes = @{ $req->{node} };
my $bphash = $req->{bootparams};
@ARGV = @{ $req->{arg} };
@@ -120,9 +125,11 @@ sub setdestiny {
#>>>>>>>used for trace log end>>>>>>>
my $state = $ARGV[0];
my $reststates;
if (@{ $req->{node} } == 0) {
xCAT::MsgUtils->trace($verbose, "d", "destiny->setdestiny: no nodes left to process, we are done");
return;
}
my @nodes = @{ $req->{node} };
my $bptab = xCAT::Table->new('bootparams', -create => 1);
my %tempbh = %{ $bptab->getNodesAttribs(\@nodes, [qw(addkcmdline)]) };
while(my ($key, $value) = each(%tempbh)) {
@@ -134,9 +141,13 @@ sub setdestiny {
}
$bptab->close();
my $state = $ARGV[0];
my $reststates;
my %nstates;
# to support the case that the state could be runimage=xxx,runimage=yyy,osimage=xxx
($state, $reststates) = split(/,/, $state, 2);
my %nstates;
chomp($state);
if ($state eq "enact") {
my $nodetypetab = xCAT::Table->new('nodetype', -create => 1);
my %nodestates;
@@ -192,11 +203,9 @@ sub setdestiny {
if ($ient->{kcmdline}) { $bphash->{kcmdline} = $ient->{kcmdline} }
}
} elsif ($state =~ /^install[=\$]/ or $state eq 'install' or $state =~ /^netboot[=\$]/ or $state eq 'netboot' or $state eq "image" or $state eq "winshell" or $state =~ /^osimage/ or $state =~ /^statelite/) {
my %state_hash;
chomp($state);
my $rawstate=$state;
my $target;
my $action;
my $rawstate=$state;
if ($state =~ /=/) {
($state, $target) = split '=', $state, 2;
@@ -213,16 +222,24 @@ sub setdestiny {
($state, $action) = split ':', $state, 2;
}
}
xCAT::MsgUtils->trace($verbose, "d", "destiny->setdestiny: state=$state, target=$target, action=$action");
my %state_hash;
# 1, Set an initial state for all requested nodes
foreach my $tmpnode (@{ $req->{node} }) {
continue if ($failurenodes{$tmpnode});
$state_hash{$tmpnode} = $state;
}
# 2, Filter those unsuitable nodes in 'state_hash'
my $nodetypetable = xCAT::Table->new('nodetype', -create => 1);
my $noderestable = xCAT::Table->new('noderes', -create => 1);
my $nbents = $noderestable->getNodeAttribs($req->{node}->[0], ["netboot"]);
my $nbents = $noderestable->getNodeAttribs($req->{node}->[0], ["netboot"]); # It is assumed that all nodes has the same `netboot` attribute
my $curnetboot = $nbents->{netboot};
if ($state ne 'osimage') {
$callback->({ error => "The options \"install\", \"netboot\", and \"statelite\" have been deprecated, use \"osimage=<osimage_name>\" instead.", errorcode => [1] });
return;
my $updateattribs;
if ($target) {
my $archentries = $nodetypetable->getNodesAttribs($req->{node}, ['supportedarchs']);
@@ -233,33 +250,46 @@ sub setdestiny {
my $nodearch = $2;
foreach (@{ $req->{node} }) {
if ($archentries->{$_}->[0]->{supportedarchs} and $archentries->{$_}->[0]->{supportedarchs} !~ /(^|,)$nodearch(\z|,)/) {
$callback->({ errorcode => [1], error => "Requested architecture " . $nodearch . " is not one of the architectures supported by $_ (per nodetype.supportedarchs, it supports " . $archentries->{$_}->[0]->{supportedarchs} . ")" });
return;
my $rsp;
$rsp->{errorcode}->[0] = 1;
$rsp->{error}->[0] = "Requested architecture " . $nodearch . " is not one of the architectures supported by $_ (per nodetype.supportedarchs, it supports " . $archentries->{$_}->[0]->{supportedarchs} . ")";
$callback->($rsp);
$failurenodes{$_} = 1;
next;
}
} #end foreach
} else {
$updateattribs->{profile} = $target;
}
} #end if($target)
$updateattribs->{provmethod} = $state;
my @tmpnodelist = @{ $req->{node} };
my @tmpnodelist = ();
foreach (@{ $req->{node} }) {
if ($failurenodes{$_}) {
delete $state_hash{$_};
continue;
}
push @tmpnodelist, $_;
}
$nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs);
} else { #state is osimage
if (@{ $req->{node} } == 0) { return; }
if ($target) {
my $osimagetable = xCAT::Table->new('osimage');
(my $ref) = $osimagetable->getAttribs({ imagename => $target }, 'provmethod', 'osvers', 'profile', 'osarch', 'imagetype');
# TODO: valid the osimage also for more madatory checking
if ($ref) {
if ($ref->{provmethod}) {
$state = $ref->{provmethod};
} else {
$errored = 1; $callback->({ errorcode => [1], error => "osimage.provmethod for $target must be set." });
$callback->({ errorcode => [1], error => "osimage.provmethod for $target must be set." });
return;
}
} else {
$errored = 1; $callback->({ errorcode => [1], error => "Cannot find the OS image $target on the osimage table." });
$callback->({ errorcode => [1], error => "Cannot find the OS image $target on the osimage table." });
return;
}
@@ -278,25 +308,39 @@ sub setdestiny {
$updateattribs->{profile} = $ref->{profile};
$updateattribs->{os} = $ref->{osvers};
$updateattribs->{arch} = $ref->{osarch};
my @tmpnodelist = @{ $req->{node} };
my @tmpnodelist = ();
foreach (@{ $req->{node} }) {
if ($failurenodes{$_}) {
delete $state_hash{$_};
continue;
}
$state_hash{$_} = $state;
push @tmpnodelist, $_;
}
$nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs);
foreach my $tmpnode (@{ $req->{node} }) {
$state_hash{$tmpnode} = $state;
}
} else {
my @errornodes = ();
#my @errornodes = ();
my $invalidosimghash;
my @validnodes;
#my @validnodes;
my $updatestuff;
my $nodetypetable = xCAT::Table->new('nodetype', -create => 1);
my %ntents = %{ $nodetypetable->getNodesAttribs($req->{node}, "provmethod") };
foreach my $tmpnode (@{ $req->{node} }) {
continue if ($failurenodes{$tmpnode});
my $osimage = $ntents{$tmpnode}->[0]->{provmethod};
if (($osimage) && ($osimage ne 'install') && ($osimage ne 'netboot') && ($osimage ne 'statelite')) {
if (!exists($updatestuff->{$osimage})) {
if (exists($updatestuff->{$osimage})) { #valid osimage
my $vnodes = $updatestuff->{$osimage}->{nodes};
push(@$vnodes, $tmpnode);
#push(@validnodes, $tmpnode);
$state_hash{$tmpnode} = $updatestuff->{$osimage}->{state};
} elsif (exists($invalidosimghash->{$osimage})) { #valid osimage
push(@{ $invalidosimghash->{$osimage}->{nodes} }, $tmpnode);
next;
}
else { #Get a new osimage, to valid it and put invalid osimage into `invalidosimghash`
my $osimagetable = xCAT::Table->new('osimage');
(my $ref) = $osimagetable->getAttribs({ imagename => $osimage }, 'provmethod', 'osvers', 'profile', 'osarch', 'imagetype');
if ($ref) {
@@ -305,7 +349,7 @@ sub setdestiny {
#if not,push the nodes into $invalidosimghash->{$osimage}->{netboot}
my $netbootval = xCAT::Utils->lookupNetboot($ref->{osvers}, $ref->{osarch}, $ref->{imagetype});
if ($netbootval =~ /$curnetboot/i) {
push(@validnodes, $tmpnode);
#push(@validnodes, $tmpnode);
} else {
push(@{ $invalidosimghash->{$osimage}->{nodes} }, $tmpnode);
$invalidosimghash->{$osimage}->{netboot} = $netbootval;
@@ -322,56 +366,69 @@ sub setdestiny {
$updatestuff->{$osimage}->{os} = $ref->{osvers};
$updatestuff->{$osimage}->{arch} = $ref->{osarch};
} else {
$errored = 1; $callback->({ errorcode => [1], error => "osimage.provmethod for $osimage must be set." });
return;
push(@{ $invalidosimghash->{$osimage}->{nodes} }, $tmpnode);
$invalidosimghash->{$osimage}->{error}->[0] = "osimage.provmethod for $osimage must be set";
next;
}
} else {
$errored = 1; $callback->({ errorcode => [1], error => "Cannot find the OS image $osimage on the osimage table." });
return;
push(@{ $invalidosimghash->{$osimage}->{nodes} }, $tmpnode);
$invalidosimghash->{$osimage}->{error}->[0] = "Cannot find the OS image $osimage on the osimage table";
next;
}
} else {
my $nodes = $updatestuff->{$osimage}->{nodes};
push(@$nodes, $tmpnode);
push(@validnodes, $tmpnode);
$state_hash{$tmpnode} = $updatestuff->{$osimage}->{state};
}
} else {
push(@errornodes, $tmpnode);
# not supported legacy mode
push(@{ $invalidosimghash->{'__xcat_legacy_mode'}->{nodes} }, $tmpnode);
$invalidosimghash->{$osimage}->{error}->[0] = "OS image name must be specified in nodetype.provmethod";
next;
}
}
if (@errornodes) {
$errored = 1; $callback->({ errorcode => [1], error => "OS image name must be specified in nodetype.provmethod for nodes: @errornodes." });
return;
} else {
foreach my $tmpimage (keys %$updatestuff) {
my $updateattribs = $updatestuff->{$tmpimage};
my @tmpnodelist = @{ $updateattribs->{nodes} };
delete $updateattribs->{nodes}; #not needed for nodetype table
delete $updateattribs->{state}; #node needed for nodetype table
$nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs);
#if any node with inappropriate noderes.netboot,report the error and return
foreach my $tmpimage (keys %$invalidosimghash) {
my @fnodes = @{ $invalidosimghash->{$tmpimage}->{nodes} };
for (@fnodes) {
$failurenodes{$_} = 1;
delete $state_hash{$_};
if ($invalidosimghash->{$tmpimage}->{error}) {
my $rsp;
$rsp->{node}->[0]->{name}->[0] = $_;
#$rsp->{node}->[0]->{errorcode}->[0] = 1;
$rsp->{node}->[0]->{error}->[0] = $invalidosimghash->{$tmpimage}->{error}->[0];
$callback->($rsp);
}
}
#if any node with inappropriate noderes.netboot,report the error and return
foreach my $tmpimage (keys %$invalidosimghash) {
#$errored =1;
$callback->({ warning => [ join(",", @{ $invalidosimghash->{$tmpimage}->{nodes} }) . ": $curnetboot might be invalid when provisioning $tmpimage,valid options: \"$invalidosimghash->{$tmpimage}->{netboot}\". \nFor more details see the 'netboot' description in the output of \"tabdump -d noderes\"." ] });
if ($invalidosimghash->{$tmpimage}->{warning})
{
my $rsp;
$rsp->{warning}->[0] = join(",", @fnodes) . ": $curnetboot might be invalid when provisioning $tmpimage,valid options: \"$invalidosimghash->{$tmpimage}->{netboot}\". \nFor more details see the 'netboot' description in the output of \"tabdump -d noderes\".";
$callback->($rsp);
}
if ("$errored" ne "0") {
return;
}
#$req->{node}=();
#push(@{$req->{node}},@validnodes);
#print Dumper($req->{node});
}
foreach my $tmpimage (keys %$updatestuff) {
my $updateattribs = $updatestuff->{$tmpimage};
my @tmpnodelist = @{ $updateattribs->{nodes} };
delete $updateattribs->{nodes}; #not needed for nodetype table
delete $updateattribs->{state}; #node needed for nodetype table
$nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs);
}
#if ("$errored" ne "0") {
# return;
#}
}
}
#print Dumper(\%state_hash);
my @validnodes = keys(%state_hash);
unless (@validnodes) {
# just return if no valid nodes left
$callback->({ errorcode => [1]});
return;
}
#if the postscripts directory exists then make sure it is
# world readable and executable by root; otherwise wget fails
my $installdir = xCAT::TableUtils->getInstallDir();
@@ -384,41 +441,43 @@ sub setdestiny {
if ($::RUNCMD_RC != 0)
{
$callback->({ info => "$cmd failed" });
}
}
#print Dumper($req);
# if precreatemypostscripts=1, create each mypostscript for each node
# 3, if precreatemypostscripts=1, create each mypostscript for each valid node
# otherwise, create it during installation /updatenode
my $notmpfiles = 0; # create tmp files if precreate=0
my $nofiles = 0; # create files, do not return array
require xCAT::Postage;
xCAT::Postage::create_mypostscript_or_not($request, $callback, $subreq, $notmpfiles, $nofiles);
my $reqcopy = {%$req};
$reqcopy->{node} = \@validnodes;
xCAT::Postage::create_mypostscript_or_not($reqcopy, $callback, $subreq, $notmpfiles, $nofiles);
# 4, Issue the sub-request for each state in 'state_hash'
my %state_hash1;
foreach my $tmpnode (keys(%state_hash)) {
push @{ $state_hash1{ $state_hash{$tmpnode} } }, $tmpnode;
}
#print Dumper(%state_hash);
#print Dumper(%state_hash1);
#print Dumper(\%state_hash1);
foreach my $tempstate (keys %state_hash1) {
my $samestatenodes = $state_hash1{$tempstate};
#print "state=$tempstate nodes=@$samestatenodes\n";
xCAT::MsgUtils->trace($verbose_on_off, "d", "destiny->process_request: issue mk$tempstate request");
xCAT::MsgUtils->trace($verbose_on_off, "d", "destiny->setdestiny: issue mk$tempstate request");
$errored = 0;
$subreq->({ command => ["mk$tempstate"],
node => $samestatenodes,
noupdateinitrd => $noupdateinitrd,
ignorekernelchk => $ignorekernelchk,
bootparams => \$bphash}, \&relay_response);
if ($errored) {
if ($errored > 1) {
# The error messeage for mkinstall/mknetboot/mkstatelite had been output within relay_response function above, don't need to output more
xCAT::MsgUtils->trace($verbose_on_off, "d", "destiny->process_request: Failed in processing mk$tempstate. Processing will not continue.");
return;
xCAT::MsgUtils->trace($verbose_on_off, "d", "destiny->setdestiny: Failed in processing mk$tempstate. Processing will not continue.");
for (@$samestatenodes) {
$failurenodes{$_} = 1;
}
next;
}
@@ -430,7 +489,8 @@ sub setdestiny {
if ($tempstate ne "winshell") {
if ($ntent and $ntent->{os}) {
$nstates{$_} .= " " . $ntent->{os};
} else { $errored = 1; $callback->({ errorcode => [1], error => "nodetype.os not defined for $_" }); }
} else {
$errored = 1; $callback->({ errorcode => [1], error => "nodetype.os not defined for $_" }); }
} else {
$nstates{$_} .= " winpe";
}
@@ -461,6 +521,37 @@ sub setdestiny {
}
}
} elsif ($state eq "shell" or $state eq "standby" or $state =~ /^runcmd/ or $state =~ /^runimage/) {
if ($state =~ /^runimage/) { # try to check the existence of the image for runimage
my @runimgcmds;
push @runimgcmds, $state;
if ($reststates) {
my @rstates = split(/,/, $reststates);
foreach (@rstates) {
if (/^runimage/) {
push @runimgcmds, $_;
}
}
}
foreach (@runimgcmds) {
my (undef, $path) = split(/=/, $_);
if ($path) {
if ($path =~ /\$/) { next; } # Ignore the path with including variable like $xcatmaster
my $cmd = "wget --spider --timeout 3 --tries=1 $path";
my @output = xCAT::Utils->runcmd("$cmd", -1);
unless (grep /^Remote file exists/, @output) {
$callback->({ error => ["Cannot get $path with wget. Could you confirm it's downloadable by wget?"], errorcode => [1] });
return;
}
} else {
$callback->({ error => "An image path should be specified to runnimage.", errorcode => [1] });
return;
}
}
}
$restab = xCAT::Table->new('noderes', -create => 1);
my $nodetype = xCAT::Table->new('nodetype');
@@ -480,8 +571,11 @@ sub setdestiny {
foreach (@nodes) {
my $ent = $enthash->{$_}->[0]; #$nodetype->getNodeAttribs($_,[qw(arch)]);
unless ($ent and $ent->{arch}) {
$callback->({ error => ["No archictecture defined in nodetype table for $_"], errorcode => [1] });
return;
my $rsp;
$rsp->{errorcode}->[0] = 1;
$rsp->{error}->[0] = "No archictecture defined in nodetype table for $_";
$callback->($rsp);
next;
}
my $arch = $ent->{arch};
if ($arch eq "ppc64le" or $arch eq "ppc64el") {
@@ -510,6 +604,14 @@ sub setdestiny {
$master = $master_entry;
}
}
unless ($master) {
my $rsp;
$rsp->{errorcode}->[0] = 1;
$rsp->{error}->[0] = "No master in site table nor noderes table for $_";
$callback->($rsp);
$failurenodes{$_} = 1;
next;
}
$ent = $hments->{$_}->[0]; #$nodehm->getNodeAttribs($_,['serialport','serialspeed','serialflow']);
if ($ent and defined($ent->{serialport})) {
@@ -521,8 +623,12 @@ sub setdestiny {
#$ent = $nodehm->getNodeAttribs($_,['serialspeed']);
unless ($ent and defined($ent->{serialspeed})) {
$callback->({ error => ["Serial port defined in noderes, but no nodehm.serialspeed set for $_"], errorcode => [1] });
return;
my $rsp;
$rsp->{errorcode}->[0] = 1;
$rsp->{error}->[0] = "Serial port defined in noderes, but no nodehm.serialspeed set for $_";
$callback->($rsp);
$failurenodes{$_} = 1;
next;
}
$kcmdline .= "," . $ent->{serialspeed};
@@ -530,10 +636,6 @@ sub setdestiny {
$kcmdline .= " ";
}
unless ($master) {
$callback->({ error => ["No master in site table nor noderes table for $_"], errorcode => [1] });
return;
}
my $xcatdport = "3001";
if (defined($port_entry)) {
$xcatdport = $port_entry;
@@ -563,35 +665,6 @@ sub setdestiny {
}
}
# try to check the existence of the image for runimage
my @runimgcmds;
if ($state =~ /^runimage/) {
push @runimgcmds, $state;
}
if ($reststates) {
my @rstates = split(/,/, $reststates);
foreach (@rstates) {
if (/^runimage/) {
push @runimgcmds, $_;
}
}
}
foreach (@runimgcmds) {
my (undef, $path) = split(/=/, $_);
if ($path) {
if ($path =~ /\$/) { next; } # Ignore the path with including variable like $xcatmaster
my $cmd = "wget --spider --timeout 3 --tries=1 $path";
my @output = xCAT::Utils->runcmd("$cmd", -1);
unless (grep /^Remote file exists/, @output) {
$callback->({ error => ["Cannot get $path with wget. Could you confirm it's downloadable by wget?"], errorcode => [1] });
return;
}
} else {
$callback->({ error => "An image path should be specified to runnimage.", errorcode => [1] });
return;
}
}
} elsif ($state eq "offline" || $state eq "shutdown") {
1;
} elsif (!($state eq "boot")) {
@@ -644,6 +717,8 @@ sub setdestiny {
if ($noupdate) { return; } #skip table manipulation if just doing 'enact'
my $updates;
foreach (@nodes) {
next if ($failurenodes{$_});
my $lstate = $state;
if ($nstates{$_}) {
$lstate = $nstates{$_};
@@ -684,16 +759,16 @@ sub nextdestiny {
$node = $request->{username}->[0];
} else {
unless ($request->{'_xcat_clienthost'}->[0]) {
#ERROR? malformed request
xCAT::MsgUtils->trace(0, "d", "destiny->nextdestiny: Cannot determine the client from the received request");
return; #nothing to do here...
}
$node = $request->{'_xcat_clienthost'}->[0];
}
($node) = noderange($node);
unless ($node) {
#not a node, don't trust it
xCAT::MsgUtils->trace(0, "d", "destiny->nextdestiny: $node is not managed yet.");
return;
}
@nodes = ($node);

View File

@@ -115,6 +115,7 @@ sub setstate {
error => [ $ipfnd[1] ],
errorcode => [1]
});
$failurenodes{$node} = 2;
return;
}
elsif ($ipfnd[0] == 2) {
@@ -145,6 +146,7 @@ sub setstate {
errorcode => [1]
}
);
$failurenodes{$node} = 2;
return;
}
} else {
@@ -223,6 +225,7 @@ sub setstate {
my $ip = xCAT::NetworkUtils->getipaddr($node);
unless ($ip) {
syslog("local1|err", "xCAT unable to resolve IP for $node in petitboot plugin");
$failurenodes{$node} = 2;
return;
}
@@ -239,23 +242,33 @@ sub setstate {
}
my $errored = 0;
sub pass_along {
my $resp = shift;
return unless ($resp);
# print Dumper($resp);
$callback->($resp);
if ($resp and ($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) {
$errored = 1;
# Global error, it normally means to stop the parent execution. For example, DB operation error.
if (($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) {
$errored = 2;
return;
}
my $failure = 0;
# Partial error on nodes, it allows to continue the rest of business on the sucessful nodes.
foreach (@{ $resp->{node} }) {
if ($_->{error} or $_->{errorcode}) {
$errored = 1;
$failure = 1;
if ($_->{name}) {
$failurenodes{$_->{name}->[0]} = 2;
}
}
}
if ( $failure ) {
$errored = $failure;
}
}
@@ -410,6 +423,7 @@ sub process_request {
my $command = $request->{command}->[0];
%breaknetbootnodes = ();
%normalnodes = (); # It will be fill-up by method: setstate.
%failurenodes = ();
#>>>>>>>used for trace log start>>>>>>>
my @args = ();
@@ -465,7 +479,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($_);
@@ -551,7 +564,7 @@ sub process_request {
node => \@nodes,
arg => [ $args[0] ] }, \&pass_along);
}
if ($errored) {
if ($errored > 1) {
my $rsp;
$rsp->{errorcode}->[0] = 1;
$rsp->{error}->[0] = "Failed in running begin prescripts.\n";
@@ -575,7 +588,7 @@ sub process_request {
arg => \@args,
bootparams => \%bphash},
\&pass_along);
if ($errored) {
if ($errored > 1) {
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Failed in processing setdestiny. Processing will not continue.");
return;
}
@@ -610,6 +623,8 @@ sub process_request {
my $tftpdir;
foreach (@nodes) {
next if ($failurenodes->{$_});
my %response;
if ($nodereshash->{$_} and $nodereshash->{$_}->[0] and $nodereshash->{$_}->[0]->{tftpdir}) {
$tftpdir = $nodereshash->{$_}->[0]->{tftpdir};
@@ -680,12 +695,12 @@ sub process_request {
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");
$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", "petitboot: issue runendpre request");
$sub_req->({ command => ['runendpre'],
node => \@nodes,
node => \@normalnodeset,
arg => [ $args[0] ] }, \&pass_along);
}
if ($errored) {