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:
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user