mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-21 19:22:05 +00:00
Merge pull request #4037 from robin2008/petitboot-error-handle-4-noderange
Enhance nodeset error handling not to exit with one node error when operating a node range
This commit is contained in:
commit
d958b50d60
@ -884,5 +884,28 @@ sub perf_log_process
|
||||
}
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------
|
||||
|
||||
=head3 report_node_error
|
||||
Using the passing callback to report node level error
|
||||
Arguments:
|
||||
$cb (callback reference)
|
||||
$node (node name)
|
||||
$msg (error message)
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
sub report_node_error
|
||||
{
|
||||
shift;
|
||||
my ($cb, $node, $msg) = @_;
|
||||
|
||||
my $rsp;
|
||||
$rsp->{node}->[0]->{name}->[0] = $node;
|
||||
$rsp->{node}->[0]->{error}->[0] = $msg;
|
||||
$rsp->{node}->[0]->{errorcode}->[0] = 1;
|
||||
$cb->($rsp);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
@ -174,43 +174,32 @@ sub mknetboot
|
||||
$statelite = "true";
|
||||
}
|
||||
my $bootparams = ${$req->{bootparams}};
|
||||
my $globaltftpdir = "/tftpboot";
|
||||
my $nodes = @{ $req->{node} };
|
||||
my @args = @{ $req->{arg} } if (exists($req->{arg}));
|
||||
my @nodes = @{ $req->{node} };
|
||||
my $noupdateinitrd = $req->{'noupdateinitrd'};
|
||||
my $ignorekernelchk = $req->{'ignorekernelchk'};
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
|
||||
#my $sitetab = xCAT::Table->new('site');
|
||||
my $linuximagetab;
|
||||
my $osimagetab;
|
||||
my %img_hash = ();
|
||||
my $installroot;
|
||||
$installroot = "/install";
|
||||
my $xcatdport = "3001";
|
||||
my $xcatiport = "3002";
|
||||
my $nodestatus = "y";
|
||||
|
||||
my @myself = xCAT::NetworkUtils->determinehostname();
|
||||
my $myname = $myself[ (scalar @myself) - 1 ];
|
||||
|
||||
#if ($sitetab)
|
||||
#{
|
||||
# (my $ref) = $sitetab->getAttribs({key => 'installdir'}, 'value');
|
||||
my @ents = xCAT::TableUtils->get_site_attribute("installdir");
|
||||
my $installroot = xCAT::TableUtils->getInstallDir();
|
||||
my $globaltftpdir = xCAT::TableUtils->getTftpDir();
|
||||
xCAT::MsgUtils->trace(0, "d", "anaconda->mknetboot: installroot=$installroot globaltftpdir=$globaltftpdir");
|
||||
|
||||
my $nodestatus = "y";
|
||||
my @ents = xCAT::TableUtils->get_site_attribute("nodestatus");
|
||||
my $site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$installroot = $site_ent;
|
||||
}
|
||||
@ents = xCAT::TableUtils->get_site_attribute("nodestatus");
|
||||
$site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$nodestatus = $site_ent;
|
||||
}
|
||||
|
||||
# ($ref) = $sitetab->getAttribs({key => 'xcatdport'}, 'value');
|
||||
@ents = xCAT::TableUtils->get_site_attribute("xcatdport");
|
||||
$site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
@ -224,14 +213,8 @@ sub mknetboot
|
||||
$xcatiport = $site_ent;
|
||||
}
|
||||
|
||||
# ($ref) = $sitetab->getAttribs({key => 'tftpdir'}, 'value');
|
||||
@ents = xCAT::TableUtils->get_site_attribute("tftpdir");
|
||||
$site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$globaltftpdir = $site_ent;
|
||||
}
|
||||
my %donetftp = ();
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
my %oents = %{ $ostab->getNodesAttribs(\@nodes, [qw(os arch profile provmethod)]) };
|
||||
my $restab = xCAT::Table->new('noderes');
|
||||
my $hmtab = xCAT::Table->new('nodehm');
|
||||
@ -240,9 +223,8 @@ sub mknetboot
|
||||
my $machash = $mactab->getNodesAttribs(\@nodes, [ 'interface', 'mac' ]);
|
||||
|
||||
my $reshash = $restab->getNodesAttribs(\@nodes, [ 'primarynic', 'tftpserver', 'tftpdir', 'xcatmaster', 'nfsserver', 'nfsdir', 'installnic' ]);
|
||||
my $hmhash =
|
||||
$hmtab->getNodesAttribs(\@nodes,
|
||||
[ 'serialport', 'serialspeed', 'serialflow' ]);
|
||||
my $hmhash = $hmtab->getNodesAttribs(\@nodes, [ 'serialport', 'serialspeed', 'serialflow' ]);
|
||||
|
||||
my $statetab;
|
||||
my $stateHash;
|
||||
if ($statelite) {
|
||||
@ -250,31 +232,6 @@ sub mknetboot
|
||||
$stateHash = $statetab->getNodesAttribs(\@nodes, ['statemnt']);
|
||||
}
|
||||
|
||||
|
||||
# Warning message for nodeset <noderange> install/netboot/statelite
|
||||
foreach my $knode (keys %oents)
|
||||
{
|
||||
my $ent = $oents{$knode}->[0];
|
||||
if ($ent && $ent->{provmethod}
|
||||
&& (($ent->{provmethod} eq 'install') || ($ent->{provmethod} eq 'netboot') || ($ent->{provmethod} eq 'statelite')))
|
||||
{
|
||||
my @ents = xCAT::TableUtils->get_site_attribute("disablenodesetwarning");
|
||||
my $site_ent = $ents[0];
|
||||
if (!defined($site_ent) || ($site_ent =~ /no/i) || ($site_ent =~ /0/))
|
||||
{
|
||||
if (!defined($::DISABLENODESETWARNING)) { # set by AAsn.pm
|
||||
$callback->(
|
||||
{
|
||||
error => ["The options \"install\", \"netboot\", and \"statelite\" have been deprecated, use \"nodeset <noderange> osimage=<osimage_name>\" instead."], errorcode => [1]
|
||||
}
|
||||
);
|
||||
|
||||
# Do not print this warning message multiple times
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach my $node (@nodes)
|
||||
{
|
||||
my $osver;
|
||||
@ -298,7 +255,9 @@ sub mknetboot
|
||||
|
||||
|
||||
my $ent = $oents{$node}->[0]; #ostab->getNodeAttribs($node, ['os', 'arch', 'profile']);
|
||||
if ($ent and $ent->{provmethod} and ($ent->{provmethod} ne 'install') and ($ent->{provmethod} ne 'netboot') and ($ent->{provmethod} ne 'statelite')) {
|
||||
if ($ent and $ent->{provmethod} and \
|
||||
($ent->{provmethod} ne 'install') and ($ent->{provmethod} ne 'netboot') and ($ent->{provmethod} ne 'statelite')) {
|
||||
|
||||
$imagename = $ent->{provmethod};
|
||||
|
||||
#print "imagename=$imagename\n";
|
||||
@ -355,9 +314,7 @@ 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] });
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "The OS image '$imagename' for node does not exist");
|
||||
next;
|
||||
}
|
||||
}
|
||||
@ -379,6 +336,10 @@ sub mknetboot
|
||||
$cfgpart = $ph->{'cfgpart'};
|
||||
}
|
||||
else {
|
||||
# This is deprecated mode to define node's provmethod, not supported now.
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "OS image name must be specified in nodetype.provmethod");
|
||||
next;
|
||||
|
||||
$osver = $ent->{os};
|
||||
$arch = $ent->{arch};
|
||||
$profile = $ent->{profile};
|
||||
@ -402,10 +363,10 @@ 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] }
|
||||
);
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
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}
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
if (!$linuximagetab) {
|
||||
@ -441,22 +402,17 @@ 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] }
|
||||
);
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
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}
|
||||
);
|
||||
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]
|
||||
}
|
||||
);
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "Insufficient nodetype entry or osimage entry for $node");
|
||||
next;
|
||||
}
|
||||
|
||||
@ -467,18 +423,16 @@ 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]
|
||||
});
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
qq{Did you run "genimage" before running "liteimg"? kernel cannot be found at $rootimgdir/kernel on $myname}
|
||||
);
|
||||
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]
|
||||
});
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
qq{Did you run "genimage" before running "liteimg"? initrd.gz or initrd-statelite.gz cannot be found at $rootimgdir/initrd.gz on $myname}
|
||||
);
|
||||
next;
|
||||
}
|
||||
else {
|
||||
@ -486,35 +440,32 @@ 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]
|
||||
});
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
qq{No packed image for platform $osver, architecture $arch and profile $profile, please run "liteimg" to create it.}
|
||||
);
|
||||
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]
|
||||
});
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
qq{Did you run "genimage" before running "packimage"? kernel cannot be found at $rootimgdir/kernel on $myname}
|
||||
);
|
||||
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]
|
||||
});
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
qq{Did you run "genimage" before running "packimage"? kernel cannot be found at $rootimgdir/kernel on $myname}
|
||||
);
|
||||
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] });
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
"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"
|
||||
);
|
||||
next;
|
||||
}
|
||||
}
|
||||
@ -567,21 +518,13 @@ 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) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, qq{Copying to $tftppath failed.});
|
||||
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") {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, qq{Copying to $tftppath failed.});
|
||||
next;
|
||||
}
|
||||
}
|
||||
@ -600,51 +543,24 @@ sub mknetboot
|
||||
|
||||
$ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['tftpserver']);
|
||||
|
||||
if ($ient and $ient->{xcatmaster})
|
||||
{
|
||||
if ($ient and $ient->{xcatmaster}) {
|
||||
$xcatmaster = $ient->{xcatmaster};
|
||||
} else {
|
||||
$xcatmaster = '!myipfn!'; #allow service nodes to dynamically nominate themselves as a good contact point, this is of limited use in the event that xcat is not the dhcp/tftp server
|
||||
}
|
||||
|
||||
if ($ient and $ient->{tftpserver} and $ient->{tftpserver} ne '<xcatmaster>')
|
||||
{
|
||||
if ($ient and $ient->{tftpserver} and $ient->{tftpserver} ne '<xcatmaster>') {
|
||||
$imgsrv = $ient->{tftpserver};
|
||||
}
|
||||
else
|
||||
{
|
||||
$ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['xcatmaster']);
|
||||
#if ($ient and $ient->{xcatmaster})
|
||||
#{
|
||||
# $imgsrv = $ient->{xcatmaster};
|
||||
#}
|
||||
#else
|
||||
#{
|
||||
# master not correct for service node pools
|
||||
#$ient = $sitetab->getAttribs({key => master}, value);
|
||||
#if ($ient and $ient->{value})
|
||||
#{
|
||||
# $imgsrv = $ient->{value};
|
||||
#}
|
||||
#else
|
||||
#{
|
||||
# $imgsrv = '!myipfn!';
|
||||
#}
|
||||
#}
|
||||
} else {
|
||||
$ient = $reshash->{$node}->[0];
|
||||
$imgsrv = $xcatmaster;
|
||||
}
|
||||
unless ($imgsrv)
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
error => [
|
||||
"Unable to determine or reasonably guess the image server for $node"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
unless ($imgsrv) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "Unable to determine or reasonably guess the image server for $node");
|
||||
next;
|
||||
}
|
||||
|
||||
# Start to build kcmdline
|
||||
my $kcmdline;
|
||||
|
||||
# add more arguments: XCAT=xcatmaster:xcatport NODE=<nodename>
|
||||
@ -753,11 +669,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 ";
|
||||
@ -826,20 +740,11 @@ sub mknetboot
|
||||
}
|
||||
|
||||
|
||||
if (defined $sent->{serialport})
|
||||
{
|
||||
if (defined $sent->{serialport}) {
|
||||
|
||||
#my $sent = $hmtab->getNodeAttribs($node,['serialspeed','serialflow']);
|
||||
unless ($sent->{serialspeed})
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
error => [
|
||||
"serialport defined, but no serialspeed for $node in nodehm table"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
unless ($sent->{serialspeed}) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,"serialport defined, but no serialspeed for $node in nodehm table");
|
||||
next;
|
||||
}
|
||||
if ($arch =~ /ppc64/i) {
|
||||
@ -966,16 +871,11 @@ sub mkinstall
|
||||
my $ignorekernelchk = $request->{'ignorekernelchk'};
|
||||
my $bootparams = ${$request->{bootparams}};
|
||||
|
||||
#my $sitetab = xCAT::Table->new('site');
|
||||
my $linuximagetab;
|
||||
my $osimagetab;
|
||||
my $osdistrouptab;
|
||||
my %img_hash = ();
|
||||
|
||||
my $installroot;
|
||||
my $globaltftpdir;
|
||||
$installroot = "/install";
|
||||
$globaltftpdir = "/tftpboot";
|
||||
|
||||
#>>>>>>>used for trace log start>>>>>>>
|
||||
my @args = ();
|
||||
@ -992,27 +892,11 @@ sub mkinstall
|
||||
|
||||
#>>>>>>>used for trace log end>>>>>>>
|
||||
|
||||
#if ($sitetab)
|
||||
#{
|
||||
# (my $ref) = $sitetab->getAttribs({key => 'installdir'}, 'value');
|
||||
my @ents = xCAT::TableUtils->get_site_attribute("installdir");
|
||||
my $site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$installroot = $site_ent;
|
||||
}
|
||||
|
||||
#( $ref) = $sitetab->getAttribs({key => 'tftpdir'}, 'value');
|
||||
@ents = xCAT::TableUtils->get_site_attribute("tftpdir");
|
||||
$site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$globaltftpdir = $site_ent;
|
||||
}
|
||||
my $installroot = xCAT::TableUtils->getInstallDir();
|
||||
my $globaltftpdir = xCAT::TableUtils->getTftpDir();
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "anaconda->mkinstall: installroot=$installroot globaltftpdir=$globaltftpdir");
|
||||
|
||||
#}
|
||||
|
||||
my $node;
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
my %donetftp;
|
||||
@ -1028,30 +912,6 @@ sub mkinstall
|
||||
|
||||
require xCAT::Template;
|
||||
|
||||
# Warning message for nodeset <noderange> install/netboot/statelite
|
||||
foreach my $knode (keys %osents)
|
||||
{
|
||||
my $ent = $osents{$knode}->[0];
|
||||
if ($ent && $ent->{provmethod}
|
||||
&& (($ent->{provmethod} eq 'install') || ($ent->{provmethod} eq 'netboot') || ($ent->{provmethod} eq 'statelite')))
|
||||
{
|
||||
my @ents = xCAT::TableUtils->get_site_attribute("disablenodesetwarning");
|
||||
my $site_ent = $ents[0];
|
||||
if (!defined($site_ent) || ($site_ent =~ /no/i) || ($site_ent =~ /0/))
|
||||
{
|
||||
if (!defined($::DISABLENODESETWARNING)) { # set by AAsn.pm
|
||||
$callback->(
|
||||
{
|
||||
error => ["The options \"install\", \"netboot\", and \"statelite\" have been deprecated, use \"nodeset <noderange> osimage=<osimage_name>\" instead."], errorcode => [1]
|
||||
}
|
||||
);
|
||||
|
||||
# Do not print this warning message multiple times
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach $node (@nodes)
|
||||
{
|
||||
my $os;
|
||||
@ -1188,9 +1048,7 @@ sub mkinstall
|
||||
$img_hash{$imagename}->{'osupdir'} = $osdisupdir;
|
||||
}
|
||||
} else {
|
||||
$callback->(
|
||||
{ error => ["The os image $imagename does not exists on the osimage table for $node"],
|
||||
errorcode => [1] });
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "The OS image '$imagename' for this node does not exist.");
|
||||
next;
|
||||
}
|
||||
}
|
||||
@ -1215,6 +1073,10 @@ sub mkinstall
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "anaconda->mkinstall: imagename=$imagename pkgdir=$pkgdir pkglistfile=$pkglistfile tmplfile=$tmplfile partfile=$partfile");
|
||||
}
|
||||
else {
|
||||
# Not support the depreate mode now.
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "OS image name must be specified in nodetype.provmethod");
|
||||
next;
|
||||
|
||||
$os = $ent->{os};
|
||||
$arch = $ent->{arch};
|
||||
$profile = $ent->{profile};
|
||||
@ -1290,29 +1152,15 @@ sub mkinstall
|
||||
if ($imagename) { push @missingparms, "osimage.profile"; }
|
||||
else { push @missingparms, "nodetype.profile"; }
|
||||
}
|
||||
unless ($os and $arch and $profile)
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
error => [ "Missing " . join(',', @missingparms) . " for $node" ],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
unless ($os and $arch and $profile) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "Missing " . join(',', @missingparms) . " for $node");
|
||||
next; #No profile
|
||||
}
|
||||
|
||||
unless (-r "$tmplfile")
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
error => [
|
||||
"No $platform kickstart template exists for "
|
||||
. $profile
|
||||
. " in directory $installroot/custom/install/$platform or $::XCATROOT/share/xcat/install/$platform"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
unless (-r "$tmplfile") {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node,
|
||||
"No $platform kickstart template exists for " . $profile . " in directory $installroot/custom/install/$platform or $::XCATROOT/share/xcat/install/$platform"
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
@ -1340,14 +1188,8 @@ sub mkinstall
|
||||
);
|
||||
}
|
||||
|
||||
if ($tmperr)
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
node =>
|
||||
[ { name => [$node], error => [$tmperr], errorcode => [1] } ]
|
||||
}
|
||||
);
|
||||
if ($tmperr) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, $tmperr);
|
||||
next;
|
||||
}
|
||||
|
||||
@ -1517,14 +1359,8 @@ sub mkinstall
|
||||
if ($::XCATSITEVALS{managedaddressmode} =~ /static/) {
|
||||
my ($ipaddr, $hostname, $gateway, $netmask) = xCAT::NetworkUtils->getNodeNetworkCfg($node);
|
||||
unless ($ipaddr) {
|
||||
$callback->(
|
||||
{
|
||||
error => [
|
||||
"cannot resolve the ip address of $node"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "cannot resolve the ip address of $node");
|
||||
next;
|
||||
}
|
||||
|
||||
if ($gateway eq '<xcatmaster>') {
|
||||
@ -1607,18 +1443,9 @@ sub mkinstall
|
||||
|
||||
|
||||
#TODO: dd=<url> for driver disks
|
||||
if (defined($sent->{serialport}))
|
||||
{
|
||||
unless ($sent->{serialspeed})
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
error => [
|
||||
"serialport defined, but no serialspeed for $node in nodehm table"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
if (defined($sent->{serialport})) {
|
||||
unless ($sent->{serialspeed}) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "serialport defined, but no serialspeed for this node in nodehm table");
|
||||
next;
|
||||
}
|
||||
|
||||
@ -1640,8 +1467,7 @@ sub mkinstall
|
||||
$kcmdline .= " console=tty0 console=ttyS" . $sent->{serialport} . "," . $sent->{serialspeed};
|
||||
}
|
||||
|
||||
if ($sent->{serialflow} =~ /(hard|cts|ctsrts)/)
|
||||
{
|
||||
if ($sent->{serialflow} =~ /(hard|cts|ctsrts)/) {
|
||||
$kcmdline .= "n8r";
|
||||
}
|
||||
}
|
||||
@ -1680,16 +1506,11 @@ sub mkinstall
|
||||
$bootparams->{$node}->[0]->{initrd} = $i;
|
||||
$bootparams->{$node}->[0]->{kcmdline} = $kcmdline;
|
||||
}
|
||||
else
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
error => ["Install image not found in $pkgdir"],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
else {
|
||||
xCAT::MsgUtils->report_node_error($callback, $node, "Install image not found in $pkgdir");
|
||||
next;
|
||||
}
|
||||
}
|
||||
} # end foreach node
|
||||
|
||||
#my $rc = xCAT::TableUtils->create_postscripts_tar();
|
||||
#if ($rc != 0)
|
||||
@ -1709,23 +1530,10 @@ sub mksysclone
|
||||
my $osimagetab;
|
||||
my %img_hash = ();
|
||||
|
||||
my $installroot;
|
||||
my $globaltftpdir;
|
||||
$installroot = "/install";
|
||||
$globaltftpdir = "/tftpboot";
|
||||
my $installroot = xCAT::TableUtils->getInstallDir();
|
||||
my $globaltftpdir = xCAT::TableUtils->getTftpDir();
|
||||
xCAT::MsgUtils->trace(0, "d", "anaconda->mksysclone: installroot=$installroot globaltftpdir=$globaltftpdir");
|
||||
|
||||
my @ents = xCAT::TableUtils->get_site_attribute("installdir");
|
||||
my $site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$installroot = $site_ent;
|
||||
}
|
||||
@ents = xCAT::TableUtils->get_site_attribute("tftpdir");
|
||||
$site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$globaltftpdir = $site_ent;
|
||||
}
|
||||
|
||||
my $node;
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
@ -2294,8 +2102,7 @@ sub copycd
|
||||
{
|
||||
$callback->(
|
||||
{
|
||||
error =>
|
||||
"Requested distribution architecture $arch, but media is $darch"
|
||||
error => "Requested distribution architecture $arch, but media is $darch"
|
||||
}
|
||||
);
|
||||
return;
|
||||
|
@ -35,6 +35,7 @@ my $tftpdir = "/tftpboot";
|
||||
|
||||
|
||||
my $nonodestatus = 0;
|
||||
my %failurenodes = ();
|
||||
|
||||
#my $sitetab = xCAT::Table->new('site');
|
||||
#if ($sitetab) {
|
||||
@ -64,36 +65,62 @@ sub process_request {
|
||||
my $result = xCAT::TableUtils->checkCredFiles($callback);
|
||||
}
|
||||
if ($request->{command}->[0] eq 'getdestiny') {
|
||||
getdestiny(0);
|
||||
}
|
||||
if ($request->{command}->[0] eq 'nextdestiny') {
|
||||
xCAT::MsgUtils->trace(0, "d", "destiny->process_request: starting getdestiny...");
|
||||
my @nodes;
|
||||
if ($request->{node}) {
|
||||
if (ref($request->{node})) {
|
||||
@nodes = @{ $request->{node} };
|
||||
} else {
|
||||
@nodes = ($request->{node});
|
||||
}
|
||||
} else { # a client asking for it's own destiny.
|
||||
unless ($request->{'_xcat_clienthost'}->[0]) {
|
||||
$callback->({ destiny => ['discover'] });
|
||||
return;
|
||||
}
|
||||
my ($node) = noderange($request->{'_xcat_clienthost'}->[0]);
|
||||
unless ($node) { # it had a valid hostname, but isn't a node
|
||||
$callback->({ destiny => ['discover'] });
|
||||
return;
|
||||
}
|
||||
@nodes = ($node);
|
||||
}
|
||||
getdestiny(0, \@nodes);
|
||||
|
||||
} 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 = 1;
|
||||
}
|
||||
# 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 +128,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 +146,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 +162,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;
|
||||
@ -175,7 +207,7 @@ sub setdestiny {
|
||||
} elsif ($state eq "iscsiboot") {
|
||||
my $iscsitab = xCAT::Table->new('iscsi');
|
||||
unless ($iscsitab) {
|
||||
$callback->({ error => "Unable to open iscsi table to get iscsiboot parameters", errorcode => [1] });
|
||||
$callback->({ error => "Unable to open iscsi table to get iscsiboot parameters", errorcode => [1], errorabort => [1] });
|
||||
}
|
||||
my $nodetype = xCAT::Table->new('nodetype');
|
||||
my $ntents = $nodetype->getNodesAttribs($req->{node}, [qw(os arch profile)]);
|
||||
@ -184,7 +216,10 @@ sub setdestiny {
|
||||
my $ient = $ients->{$_}->[0]; #$iscsitab->getNodeAttribs($_,[qw(kernel kcmdline initrd)]);
|
||||
my $ntent = $ntents->{$_}->[0];
|
||||
unless ($ient and $ient->{kernel}) {
|
||||
unless ($ntent and $ntent->{arch} =~ /x86/ and -f ("$tftpdir/undionly.kpxe" or -f "$tftpdir/xcat/xnba.kpxe")) { $callback->({ error => "$_: No iscsi boot data available", errorcode => [1] }); } #If x86 node and undionly.kpxe exists, presume they know what they are doing
|
||||
unless ($ntent and $ntent->{arch} =~ /x86/ and -f ("$tftpdir/undionly.kpxe" or -f "$tftpdir/xcat/xnba.kpxe")) {
|
||||
$failurenodes{$_} = 1;
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "No iscsi boot data available");
|
||||
} #If x86 node and undionly.kpxe exists, presume they know what they are doing
|
||||
next;
|
||||
}
|
||||
$bphash->{kernel} = $ient->{kernel};
|
||||
@ -192,8 +227,6 @@ 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 $target;
|
||||
my $action;
|
||||
my $rawstate=$state;
|
||||
@ -213,16 +246,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} }) {
|
||||
next 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], errorabort => [1] });
|
||||
return;
|
||||
|
||||
my $updateattribs;
|
||||
if ($target) {
|
||||
my $archentries = $nodetypetable->getNodesAttribs($req->{node}, ['supportedarchs']);
|
||||
@ -233,33 +274,44 @@ 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;
|
||||
xCAT::MsgUtils->report_node_error($callback, $_,
|
||||
"Requested architecture " . $nodearch . " is not one of the architectures supported by $_ (per nodetype.supportedarchs, it supports " . $archentries->{$_}->[0]->{supportedarchs} . ")"
|
||||
);
|
||||
$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{$_};
|
||||
next;
|
||||
}
|
||||
push @tmpnodelist, $_;
|
||||
}
|
||||
$nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs);
|
||||
|
||||
} else { #state is osimage
|
||||
if (@{ $req->{node} } == 0) { return; }
|
||||
if ($target) {
|
||||
if (@{ $req->{node} } == 0) { return; }
|
||||
my $osimagetable = xCAT::Table->new('osimage');
|
||||
(my $ref) = $osimagetable->getAttribs({ imagename => $target }, 'provmethod', 'osvers', 'profile', 'osarch', 'imagetype');
|
||||
|
||||
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.", errorabort => [1] });
|
||||
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.", errorabort => [1] });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -278,25 +330,37 @@ sub setdestiny {
|
||||
$updateattribs->{profile} = $ref->{profile};
|
||||
$updateattribs->{os} = $ref->{osvers};
|
||||
$updateattribs->{arch} = $ref->{osarch};
|
||||
my @tmpnodelist = @{ $req->{node} };
|
||||
my @tmpnodelist = ();
|
||||
foreach ( @nodes ) {
|
||||
if (exists($failurenodes{$_})) {
|
||||
delete $state_hash{$_};
|
||||
next;
|
||||
}
|
||||
$state_hash{$_} = $state;
|
||||
push @tmpnodelist, $_;
|
||||
}
|
||||
$nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs);
|
||||
|
||||
|
||||
foreach my $tmpnode (@{ $req->{node} }) {
|
||||
$state_hash{$tmpnode} = $state;
|
||||
}
|
||||
|
||||
} else {
|
||||
my @errornodes = ();
|
||||
my $invalidosimghash;
|
||||
my @validnodes;
|
||||
my $updatestuff;
|
||||
my $nodetypetable = xCAT::Table->new('nodetype', -create => 1);
|
||||
my %ntents = %{ $nodetypetable->getNodesAttribs($req->{node}, "provmethod") };
|
||||
foreach my $tmpnode (@{ $req->{node} }) {
|
||||
|
||||
foreach my $tmpnode (@nodes) {
|
||||
next if (exists($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);
|
||||
$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,14 +369,14 @@ 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);
|
||||
1;
|
||||
} else {
|
||||
push(@{ $invalidosimghash->{$osimage}->{nodes} }, $tmpnode);
|
||||
$invalidosimghash->{$osimage}->{netboot} = $netbootval;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($ref->{provmethod}) {
|
||||
if ($ref->{provmethod} && $ref->{profile} && $ref->{osvers} && $ref->{osarch}) {
|
||||
$state = $ref->{provmethod};
|
||||
$state_hash{$tmpnode} = $state;
|
||||
|
||||
@ -322,93 +386,112 @@ 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, osimage.osvers, osimage.osarch and osimage.profile 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_provmethod_mode}->{nodes} }, $tmpnode);
|
||||
$invalidosimghash->{__xcat_legacy_provmethod_mode}->{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 warning
|
||||
foreach my $tmpimage (keys %$invalidosimghash) {
|
||||
my @fnodes = @{ $invalidosimghash->{$tmpimage}->{nodes} };
|
||||
for (@fnodes) {
|
||||
$failurenodes{$_} = 1;
|
||||
delete $state_hash{$_};
|
||||
if ($invalidosimghash->{$tmpimage}->{error}) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, $invalidosimghash->{$tmpimage}->{error}->[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#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\"." ] });
|
||||
my $netbootwarn = $invalidosimghash->{$tmpimage}->{netboot};
|
||||
if ($netbootwarn) {
|
||||
my $rsp;
|
||||
$rsp->{warning}->[0] = join(",", @fnodes) . ": $curnetboot might be invalid when provisioning $tmpimage,valid options: \"$netbootwarn\". \nFor more details see the 'netboot' description in the output of \"tabdump -d noderes\".";
|
||||
$callback->($rsp);
|
||||
}
|
||||
}
|
||||
|
||||
if ("$errored" ne "0") {
|
||||
return;
|
||||
}
|
||||
# upddate DB for the nodes which pass the checking
|
||||
foreach my $tmpimage (keys %$updatestuff) {
|
||||
my $updateattribs = $updatestuff->{$tmpimage};
|
||||
my @tmpnodelist = @{ $updateattribs->{nodes} };
|
||||
|
||||
#$req->{node}=();
|
||||
#push(@{$req->{node}},@validnodes);
|
||||
#print Dumper($req->{node});
|
||||
delete $updateattribs->{nodes}; #not needed for nodetype table
|
||||
delete $updateattribs->{state}; #node needed for nodetype table
|
||||
$nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs);
|
||||
}
|
||||
}
|
||||
|
||||
if (%state_hash) { # To valide mac here
|
||||
my @tempnodes = keys(%state_hash);
|
||||
my $mactab = xCAT::Table->new('mac', -create => 1);
|
||||
my $machash = $mactab->getNodesAttribs(\@tempnodes, ['mac']);
|
||||
|
||||
foreach (@tempnodes) {
|
||||
my $macs = $machash->{$_}->[0];
|
||||
unless ($macs and $macs->{mac}) {
|
||||
$failurenodes{$_} = 1;
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "No MAC address available for this node");
|
||||
delete $state_hash{$_};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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();
|
||||
my $postscripts = "$installdir/postscripts";
|
||||
if (-e $postscripts)
|
||||
{
|
||||
if (-e $postscripts) {
|
||||
my $cmd = "chmod -R a+r $postscripts";
|
||||
xCAT::Utils->runcmd($cmd, 0);
|
||||
my $rsp = {};
|
||||
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
|
||||
my $reqcopy = {%$req};
|
||||
$reqcopy->{node} = \@validnodes;
|
||||
require xCAT::Postage;
|
||||
xCAT::Postage::create_mypostscript_or_not($request, $callback, $subreq, $notmpfiles, $nofiles);
|
||||
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,
|
||||
@ -417,32 +500,46 @@ sub setdestiny {
|
||||
bootparams => \$bphash}, \&relay_response);
|
||||
if ($errored) {
|
||||
# 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.");
|
||||
next if ($errored > 1);
|
||||
}
|
||||
|
||||
|
||||
my $ntents = $nodetypetable->getNodesAttribs($samestatenodes, [qw(os arch profile)]);
|
||||
my $updates;
|
||||
foreach (@{$samestatenodes}) {
|
||||
next if (exists($failurenodes{$_})); #Filter the failure nodes
|
||||
|
||||
$nstates{$_} = $tempstate; #local copy of state variable for mod
|
||||
my $ntent = $ntents->{$_}->[0]; #$nodetype->getNodeAttribs($_,[qw(os arch profile)]);
|
||||
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 {
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "nodetype.os not defined for $_.");
|
||||
$failurenodes{$_} = 1;
|
||||
next;
|
||||
}
|
||||
} else {
|
||||
$nstates{$_} .= " winpe";
|
||||
}
|
||||
if ($ntent and $ntent->{arch}) {
|
||||
$nstates{$_} .= "-" . $ntent->{arch};
|
||||
} else { $errored = 1; $callback->({ errorcode => [1], error => "nodetype.arch not defined for $_" }); }
|
||||
} else {
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "nodetype.arch not defined for $_.");
|
||||
$failurenodes{$_} = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
if (($tempstate ne "winshell") && ($tempstate ne "sysclone")) {
|
||||
if ($ntent and $ntent->{profile}) {
|
||||
$nstates{$_} .= "-" . $ntent->{profile};
|
||||
} else { $errored = 1; $callback->({ errorcode => [1], error => "nodetype.profile not defined for $_" }); }
|
||||
} else {
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "nodetype.profile not defined for $_.");
|
||||
$failurenodes{$_} = 1;
|
||||
next;
|
||||
}
|
||||
}
|
||||
if ($errored) { return; }
|
||||
$updates->{$_}->{'currchain'} = "boot";
|
||||
}
|
||||
unless ($tempstate =~ /^netboot|^statelite/) {
|
||||
@ -461,6 +558,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], errorabort => [1]});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$callback->({ error => "An image path should be specified to runimage.", errorcode => [1], errorabort => [1] });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$restab = xCAT::Table->new('noderes', -create => 1);
|
||||
my $nodetype = xCAT::Table->new('nodetype');
|
||||
|
||||
@ -480,8 +608,9 @@ 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;
|
||||
$failurenodes{$_} = 1;
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "No archictecture defined in nodetype table for the node.");
|
||||
next;
|
||||
}
|
||||
my $arch = $ent->{arch};
|
||||
if ($arch eq "ppc64le" or $arch eq "ppc64el") {
|
||||
@ -510,6 +639,11 @@ sub setdestiny {
|
||||
$master = $master_entry;
|
||||
}
|
||||
}
|
||||
unless ($master) {
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "No master in site table nor noderes table for the node.");
|
||||
$failurenodes{$_} = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
$ent = $hments->{$_}->[0]; #$nodehm->getNodeAttribs($_,['serialport','serialspeed','serialflow']);
|
||||
if ($ent and defined($ent->{serialport})) {
|
||||
@ -521,8 +655,9 @@ 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;
|
||||
xCAT::MsgUtils->report_node_error($callback, $_, "serialport defined, but no serialspeed for this node in nodehm table");
|
||||
$failurenodes{$_} = 1;
|
||||
next;
|
||||
}
|
||||
$kcmdline .= "," . $ent->{serialspeed};
|
||||
|
||||
@ -530,10 +665,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,39 +694,21 @@ 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")) {
|
||||
$callback->({ error => ["Unknown state $state requested"], errorcode => [1] });
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#Exclude the failure nodes
|
||||
my @normalnodes = ();
|
||||
foreach (@nodes) {
|
||||
next if (exists($failurenodes{$_})); #Filter the failure nodes
|
||||
push @normalnodes, $_;
|
||||
}
|
||||
|
||||
unless (@normalnodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -603,10 +716,10 @@ sub setdestiny {
|
||||
if ($state eq "iscsiboot" or $state eq "boot") {
|
||||
my $nodetype = xCAT::Table->new('nodetype', -create => 1);
|
||||
my $osimagetab = xCAT::Table->new('osimage', -create => 1);
|
||||
my $ntents = $nodetype->getNodesAttribs($req->{node}, [qw(os arch profile provmethod)]);
|
||||
my $ntents = $nodetype->getNodesAttribs(\@normalnodes, [qw(os arch profile provmethod)]);
|
||||
my @nodestoblank = ();
|
||||
my %osimage_hash = ();
|
||||
foreach (@{ $req->{node} }) {
|
||||
foreach (@normalnodes) {
|
||||
my $ntent = $ntents->{$_}->[0];
|
||||
|
||||
#if the previous nodeset staute is not install, then blank nodetype.provmethod
|
||||
@ -643,7 +756,8 @@ sub setdestiny {
|
||||
|
||||
if ($noupdate) { return; } #skip table manipulation if just doing 'enact'
|
||||
my $updates;
|
||||
foreach (@nodes) {
|
||||
foreach (@normalnodes) {
|
||||
|
||||
my $lstate = $state;
|
||||
if ($nstates{$_}) {
|
||||
$lstate = $nstates{$_};
|
||||
@ -657,7 +771,7 @@ sub setdestiny {
|
||||
}
|
||||
}
|
||||
$chaintab->setNodesAttribs($updates);
|
||||
return getdestiny($flag + 1);
|
||||
return getdestiny($flag + 1, \@normalnodes);
|
||||
}
|
||||
|
||||
|
||||
@ -684,16 +798,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);
|
||||
@ -757,40 +871,22 @@ sub nextdestiny {
|
||||
|
||||
sub getdestiny {
|
||||
my $flag = shift;
|
||||
my $nodes = shift;
|
||||
|
||||
# flag value:
|
||||
# 0--getdestiny is called by dodestiny
|
||||
# 1--called by nextdestiny in dodestiny. The node calls nextdestiny before boot and runcmd.
|
||||
# 2--called by nodeset command
|
||||
# 3--called by updateflag after the node finished installation and before booting
|
||||
my @args;
|
||||
my @nodes;
|
||||
if ($request->{node}) {
|
||||
if (ref($request->{node})) {
|
||||
@nodes = @{ $request->{node} };
|
||||
} else {
|
||||
@nodes = ($request->{node});
|
||||
}
|
||||
} else { # a client asking for it's own destiny.
|
||||
unless ($request->{'_xcat_clienthost'}->[0]) {
|
||||
$callback->({ destiny => ['discover'] });
|
||||
return;
|
||||
}
|
||||
my ($node) = noderange($request->{'_xcat_clienthost'}->[0]);
|
||||
unless ($node) { # it had a valid hostname, but isn't a node
|
||||
$callback->({ destiny => ['discover'] });
|
||||
return;
|
||||
}
|
||||
@nodes = ($node);
|
||||
}
|
||||
|
||||
my $node;
|
||||
xCAT::MsgUtils->trace(0, "d", "destiny->process_request: getdestiny...");
|
||||
$restab = xCAT::Table->new('noderes');
|
||||
my $chaintab = xCAT::Table->new('chain');
|
||||
my $chainents = $chaintab->getNodesAttribs(\@nodes, [qw(currstate chain)]);
|
||||
my $nrents = $restab->getNodesAttribs(\@nodes, [qw(tftpserver xcatmaster)]);
|
||||
my $chainents = $chaintab->getNodesAttribs($nodes, [qw(currstate chain)]);
|
||||
my $nrents = $restab->getNodesAttribs($nodes, [qw(tftpserver xcatmaster)]);
|
||||
my $bptab = xCAT::Table->new('bootparams', -create => 1);
|
||||
my $bpents = $bptab->getNodesAttribs(\@nodes, [qw(kernel initrd kcmdline xcatmaster)]);
|
||||
my $bpents = $bptab->getNodesAttribs($nodes, [qw(kernel initrd kcmdline xcatmaster)]);
|
||||
|
||||
#my $sitetab= xCAT::Table->new('site');
|
||||
#(my $sent) = $sitetab->getAttribs({key=>'master'},'value');
|
||||
@ -798,7 +894,7 @@ sub getdestiny {
|
||||
my $master_value = $entries[0];
|
||||
|
||||
my %node_status = ();
|
||||
foreach $node (@nodes) {
|
||||
foreach $node (@$nodes) {
|
||||
unless ($chaintab) { #Without destiny, have the node wait with ssh hopefully open at least
|
||||
$callback->({ node => [ { name => [$node], data => ['standby'], destiny => ['standby'] } ] });
|
||||
return;
|
||||
|
@ -14,8 +14,6 @@ use Getopt::Long;
|
||||
use xCAT::Table;
|
||||
use xCAT::Usage;
|
||||
my $request;
|
||||
my %breaknetbootnodes;
|
||||
our %normalnodes;
|
||||
my %tftpserverip;
|
||||
my $callback;
|
||||
my $sub_req;
|
||||
@ -102,18 +100,14 @@ sub setstate {
|
||||
my $tftpdir = shift;
|
||||
my %nrhash = %{ shift() };
|
||||
my $linuximghash = shift();
|
||||
my $nodearch = shift;
|
||||
my $kern = $bphash{$node}->[0]; #$bptab->getNodeAttribs($node,['kernel','initrd','kcmdline']);
|
||||
if ($kern->{kcmdline} =~ /!myipfn!/) {
|
||||
my $ipfn;
|
||||
my @ipfnd = xCAT::NetworkUtils->my_ip_facing($node);
|
||||
|
||||
if ($ipfnd[0] == 1) {
|
||||
$::callback->(
|
||||
{
|
||||
error => [ $ipfnd[1] ],
|
||||
errorcode => [1]
|
||||
});
|
||||
return;
|
||||
return (1, $ipfnd[1]);
|
||||
}
|
||||
elsif ($ipfnd[0] == 2) {
|
||||
my $servicenodes = $nrhash{$node}->[0];
|
||||
@ -123,27 +117,11 @@ sub setstate {
|
||||
|
||||
# We are in the service node pools, print error if no facing ip.
|
||||
if (xCAT::InstUtils->is_me($sn)) {
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$::myxcatname: $ipfnd[1] on service node $sn"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
return;
|
||||
return (1, "$::myxcatname: $ipfnd[1] on service node $sn");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$::myxcatname: $ipfnd[1]"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
return;
|
||||
return (1, "$::myxcatname: $ipfnd[1]");
|
||||
}
|
||||
} else {
|
||||
$ipfn = $ipfnd[1];
|
||||
@ -178,15 +156,17 @@ sub setstate {
|
||||
unless (-d "$bootloader_root") {
|
||||
mkpath("$bootloader_root");
|
||||
}
|
||||
my $nodemac;
|
||||
my %client_nethash = xCAT::DBobjUtils->getNetwkInfo([$node]);
|
||||
|
||||
my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']);
|
||||
my $cref = $chainhash{$node}->[0];
|
||||
unless ($cref->{currstate}) { # the currstate should be set during 'setdestiny'
|
||||
return (1, "Cannot determine current state for this node");
|
||||
}
|
||||
|
||||
# remove the old boot configuration files and create a new one, but only if not offline directive
|
||||
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") {
|
||||
if ($cref->{currstate} ne "offline") {
|
||||
open($pcfg, '>', "$bootloader_root/" . $node);
|
||||
print $pcfg "#" . $cref->{currstate} . "\n";
|
||||
|
||||
@ -197,15 +177,7 @@ sub setstate {
|
||||
print $pcfg "set timeout=5\n";
|
||||
}
|
||||
|
||||
$normalnodes{$node} = 1; #Assume a normal netboot (well, normal dhcp,
|
||||
#which is normally with a valid 'filename' field,
|
||||
#but the typical ppc case will be 'special' makedhcp
|
||||
#to clear the filename field, so the logic is a little
|
||||
#opposite
|
||||
|
||||
if ($cref and $cref->{currstate} eq "boot") {
|
||||
$breaknetbootnodes{$node} = 1;
|
||||
delete $normalnodes{$node}; #Signify to omit this from one makedhcp command
|
||||
if ($cref->{currstate} eq "boot") {
|
||||
close($pcfg);
|
||||
} elsif ($kern and $kern->{kernel}) {
|
||||
|
||||
@ -226,26 +198,24 @@ sub setstate {
|
||||
my @nxtsrvd = xCAT::NetworkUtils->my_ip_facing($node);
|
||||
unless ($nxtsrvd[0]) {
|
||||
$serverip = $nxtsrvd[1];
|
||||
} else {
|
||||
$callback->({ error => [ $nxtsrvd[1] ], errorcode => [1] });
|
||||
return;
|
||||
} else {
|
||||
return (1, $nxtsrvd[1]);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
if (defined($tftpserverip{$tftpserver})) {
|
||||
$serverip = $tftpserverip{$tftpserver};
|
||||
} else {
|
||||
$serverip = xCAT::NetworkUtils->getipaddr($tftpserver);
|
||||
unless ($serverip) {
|
||||
syslog("local1|err", "xCAT unable to resolve $tftpserver");
|
||||
return;
|
||||
return (1, "xCAT unable to resolve $tftpserver");
|
||||
}
|
||||
$tftpserverip{$tftpserver} = $serverip;
|
||||
}
|
||||
}
|
||||
|
||||
unless($serverip){
|
||||
$callback->({ error => ["Unable to determine the tftpserver for $node"], errorcode => [1] });
|
||||
return;
|
||||
close($pcfg);
|
||||
return (1, "Unable to determine the tftpserver for $node");
|
||||
}
|
||||
my $grub2protocol = "tftp";
|
||||
if (defined($nrhash{$node}->[0]) && $nrhash{$node}->[0]->{'netboot'}
|
||||
@ -254,15 +224,8 @@ sub setstate {
|
||||
}
|
||||
|
||||
unless ($grub2protocol =~ /^http|tftp$/) {
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"Invalid netboot method, please check noderes.netboot for $node"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
return;
|
||||
close($pcfg);
|
||||
return (1, "Invalid netboot method, please check noderes.netboot for $node");
|
||||
}
|
||||
|
||||
# write entries to boot config file, but only if not offline directive
|
||||
@ -296,26 +259,43 @@ sub setstate {
|
||||
} else {
|
||||
close($pcfg);
|
||||
}
|
||||
|
||||
unless ($nodearch) {
|
||||
return (1, "No archictecture defined in nodetype table for the node.");
|
||||
}
|
||||
if ($nodearch =~ /ppc64/i) {
|
||||
$nodearch = "ppc"
|
||||
}
|
||||
my $grub2bin = "$bootloader_root/grub2." . $nodearch;
|
||||
unless (-e "$grub2bin") {
|
||||
return (1, "Stop grub2 configuration for this node, \"$grub2bin\" does not exits.");
|
||||
}
|
||||
|
||||
chdir("$bootloader_root");
|
||||
if ($cref->{currstate} eq "offline" or $cref->{currstate} eq "boot") {
|
||||
unlink("grub2-$node");
|
||||
} elsif (! -e "grub2-$node") {
|
||||
symlink("grub2." . $nodearch, "grub2-$node");
|
||||
}
|
||||
|
||||
my $ip = xCAT::NetworkUtils->getipaddr($node);
|
||||
unless ($ip) {
|
||||
syslog("local1|err", "xCAT unable to resolve IP in grub2 plugin");
|
||||
return;
|
||||
return (1, "xCAT unable to resolve IP in grub2 plugin");
|
||||
}
|
||||
my $mactab = xCAT::Table->new('mac');
|
||||
#my $mactab = xCAT::Table->new('mac');
|
||||
my %ipaddrs;
|
||||
my $macstring;
|
||||
$ipaddrs{$ip} = 1;
|
||||
if ($mactab) {
|
||||
my $ment = $machash{$node}->[0]; #$mactab->getNodeAttribs($node,['mac']);
|
||||
if ($ment and $ment->{mac}) {
|
||||
$macstring = $ment->{mac};
|
||||
my @macs = split(/\|/, $ment->{mac});
|
||||
foreach (@macs) {
|
||||
if (/!(.*)/) {
|
||||
my $ipaddr = xCAT::NetworkUtils->getipaddr($1);
|
||||
if ($ipaddr) {
|
||||
$ipaddrs{$ipaddr} = 1;
|
||||
}
|
||||
|
||||
my $ment = $machash{$node}->[0];
|
||||
if ($ment and $ment->{mac}) {
|
||||
$macstring = $ment->{mac};
|
||||
my @macs = split(/\|/, $ment->{mac});
|
||||
foreach (@macs) {
|
||||
if (/!(.*)/) {
|
||||
my $ipaddr = xCAT::NetworkUtils->getipaddr($1);
|
||||
if ($ipaddr) {
|
||||
$ipaddrs{$ipaddr} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -329,11 +309,10 @@ sub setstate {
|
||||
|
||||
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
|
||||
unlink("$bootloader_root/" . $pname);
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
link("$bootloader_root/" . $node, "$bootloader_root/" . $pname);
|
||||
}
|
||||
link("$bootloader_root/" . $node, "$bootloader_root/" . $pname) if ($cref->{currstate} ne "offline");
|
||||
}
|
||||
|
||||
|
||||
my $nodemac;
|
||||
my $nrent=$nrhash{$node}->[0];
|
||||
if($nrent and $nrent->{installnic}){
|
||||
my $myinstallnic=$nrent->{installnic};
|
||||
@ -341,8 +320,6 @@ sub setstate {
|
||||
$nodemac=$myinstallnic;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (! $nodemac and $macstring) {
|
||||
$nodemac = xCAT::Utils->parseMacTabEntry($macstring, $node);
|
||||
}
|
||||
@ -354,27 +331,43 @@ sub setstate {
|
||||
|
||||
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
|
||||
unlink("$bootloader_root/" . $pname);
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
link("$bootloader_root/" . $node, "$bootloader_root/" . $pname);
|
||||
}
|
||||
link("$bootloader_root/" . $node, "$bootloader_root/" . $pname) if ($cref->{currstate} ne "offline");
|
||||
}
|
||||
return;
|
||||
return (0, "");
|
||||
}
|
||||
|
||||
my $errored = 0;
|
||||
|
||||
sub pass_along {
|
||||
my $resp = shift;
|
||||
return unless ($resp);
|
||||
|
||||
$callback->($resp);
|
||||
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;
|
||||
}
|
||||
$callback->($resp);
|
||||
|
||||
if ($failure > 1) { # quick abort
|
||||
$errored = $failure;
|
||||
return;
|
||||
}
|
||||
|
||||
# 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -468,7 +461,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;
|
||||
}
|
||||
@ -517,11 +510,8 @@ sub preprocess_request {
|
||||
sub process_request {
|
||||
$request = shift;
|
||||
$callback = shift;
|
||||
$::callback = $callback;
|
||||
$sub_req = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
%breaknetbootnodes = ();
|
||||
%normalnodes = (); # It will be fill-up by method: setstate.
|
||||
|
||||
my @args;
|
||||
#>>>>>>>used for trace log start>>>>>>>
|
||||
@ -661,11 +651,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.\n";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Failed in running begin prescripts.");
|
||||
return if ($errored > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,8 +672,8 @@ sub process_request {
|
||||
bootparams => \%bphash
|
||||
}, \&pass_along);
|
||||
if ($errored) {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Failed in processing setdestiny. Processing will not continue.");
|
||||
return;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Failed in processing setdestiny.");
|
||||
return if ($errored > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,156 +694,62 @@ sub process_request {
|
||||
my $rc;
|
||||
my $errstr;
|
||||
|
||||
my $tftpdir;
|
||||
my @normalnodeset = ();
|
||||
foreach (@nodes) {
|
||||
my %response;
|
||||
next if (exists($failurenodes{$_}));
|
||||
|
||||
my $tftpdir = $globaltftpdir;
|
||||
if ($nodereshash->{$_} and $nodereshash->{$_}->[0] and $nodereshash->{$_}->[0]->{tftpdir}) {
|
||||
$tftpdir = $nodereshash->{$_}->[0]->{tftpdir};
|
||||
} else {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
|
||||
my %response;
|
||||
$response{node}->[0]->{name}->[0] = $_;
|
||||
if ($args[0]) { # Send it on to the destiny plugin, then setstate
|
||||
my $ent = $typehash->{$_}->[0];
|
||||
my $nodearch = $ent->{'arch'};
|
||||
my $osimgname = $ent->{'provmethod'};
|
||||
my $linuximghash = undef;
|
||||
unless ($osimgname =~ /^(install|netboot|statelite)$/) {
|
||||
$linuximghash = $linuximgtab->getAttribs({ imagename => $osimgname }, 'boottarget', 'addkcmdline');
|
||||
}
|
||||
|
||||
($rc, $errstr) = setstate($_, \%bphash, $chainhash, $machash, $tftpdir, $nrhash, $linuximghash);
|
||||
($rc, $errstr) = setstate($_, \%bphash, $chainhash, $machash, $tftpdir, $nrhash, $linuximghash, $nodearch);
|
||||
if ($rc) {
|
||||
$response{node}->[0]->{errorcode}->[0] = $rc;
|
||||
$response{node}->[0]->{errorc}->[0] = $errstr;
|
||||
$response{node}->[0]->{error}->[0] = $errstr;
|
||||
$failurenodes{$_} = 1;
|
||||
$callback->(\%response);
|
||||
} else {
|
||||
push @normalnodeset, $_;
|
||||
}
|
||||
|
||||
}
|
||||
} # end of foreach node
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Finish to handle configurations");
|
||||
|
||||
my @normalnodeset = keys %normalnodes;
|
||||
my @breaknetboot = keys %breaknetbootnodes;
|
||||
|
||||
my %osimagenodehash;
|
||||
for my $nn (@normalnodeset) {
|
||||
|
||||
#record the os version for node
|
||||
my $ent = $typehash->{$nn}->[0];
|
||||
my $osimage = $ent->{'provmethod'};
|
||||
if ($osimage =~ /^(install|netboot|statelite)$/) {
|
||||
$osimage = ($ent->{'os'}) . '-' . ($ent->{'arch'}) . '-' . ($ent->{'provmethod'}) . '-' . ($ent->{'profile'});
|
||||
}
|
||||
push @{ $osimagenodehash{$osimage} }, $nn;
|
||||
}
|
||||
|
||||
my $do_dhcpsetup = 1;
|
||||
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; }
|
||||
}
|
||||
|
||||
#Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time
|
||||
unless (($inittime) || ($args[0] eq 'offline')) {
|
||||
foreach my $osimage (keys %osimagenodehash) {
|
||||
unless ($inittime) {
|
||||
|
||||
#TOTO check the existence of grub2 executable files for corresponding arch
|
||||
my $osimgent = $osimagetab->getAttribs({ imagename => $osimage }, 'osarch');
|
||||
my $validarch = undef;
|
||||
if ($osimgent and $osimgent->{'osarch'})
|
||||
{
|
||||
$validarch = $osimgent->{'osarch'};
|
||||
}
|
||||
else
|
||||
{
|
||||
# Can not determine arch from osimage definition. This is most likely
|
||||
# the case when nodeset is "shell" or "shutdown". Look at node definition, to
|
||||
# figure out arch to use.
|
||||
|
||||
# get nodename from osimagenodehash hash
|
||||
my $node_name = $osimagenodehash{$osimage}[0];
|
||||
|
||||
# lookup node arch setting
|
||||
my $node_entry = $typetab->getNodeAttribs($node_name, ['arch']);
|
||||
if ($node_entry and $node_entry->{'arch'})
|
||||
{
|
||||
# Extracted arch from node definition
|
||||
$validarch = $node_entry->{'arch'};
|
||||
}
|
||||
else
|
||||
{
|
||||
# At this point we can not determine architecture either
|
||||
# from osimage or node definition.
|
||||
my $rsp;
|
||||
push @{ $rsp->{data} }, "Not able to determine architecture of node $node_name. Verify arch attribute setting.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
if ($validarch =~ /ppc64/i)
|
||||
{
|
||||
$validarch = "ppc"
|
||||
}
|
||||
my $grub2 = "/boot/grub2/grub2." . $validarch;
|
||||
my $tftppath = $tftpdir . $grub2;
|
||||
unless (-e "$tftppath") {
|
||||
my $rsp;
|
||||
push @{ $rsp->{data} },
|
||||
"stop configuration, missing $tftppath.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return;
|
||||
}
|
||||
chdir("$tftpdir/boot/grub2/");
|
||||
foreach my $tmp_node (@{ $osimagenodehash{$osimage} }) {
|
||||
unless (-e "grub2-$tmp_node") {
|
||||
symlink("grub2." . $validarch, "grub2-$tmp_node");
|
||||
}
|
||||
}
|
||||
if ($do_dhcpsetup) {
|
||||
if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
node => \@{ $osimagenodehash{$osimage} }, arg => ['-l'] }, $callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
node => \@{ $osimagenodehash{$osimage} } }, $callback);
|
||||
}
|
||||
}
|
||||
} #end of foreach osimagenodehash
|
||||
|
||||
foreach my $tmp_node (@breaknetboot) {
|
||||
if (-e "$tftpdir/boot/grub2/grub2-$tmp_node") {
|
||||
unlink("$tftpdir/boot/grub2/grub2-$tmp_node");
|
||||
}
|
||||
#dhcp stuff
|
||||
my $do_dhcpsetup = 1;
|
||||
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 ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
node => \@breaknetboot,
|
||||
arg => ['-l'] }, $callback);
|
||||
} else {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue makedhcp request");
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
node => \@breaknetboot }, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
# For offline operation, remove the dhcp entries whatever dhcpset is disabled in site ( existing code logic, just keep it as is)
|
||||
if ($do_dhcpsetup || $args[0] eq 'offline') {
|
||||
my @parameter;
|
||||
push @parameter, '-l' if ($request->{'_disparatetftp'}->[0]);
|
||||
push @parameter, '-d' if ($args[0] eq 'offline');
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request");
|
||||
|
||||
if ($args[0] eq 'offline') {
|
||||
my @rmdhcp_nodes;
|
||||
|
||||
# If nodeset directive was offline we need to remove the architecture file link and remove dhcp entries
|
||||
foreach my $osimage (keys %osimagenodehash) {
|
||||
foreach my $tmp_node (@{ $osimagenodehash{$osimage} }) {
|
||||
unlink("$tftpdir/boot/grub2/grub2-$tmp_node");
|
||||
push(@rmdhcp_nodes, $tmp_node);
|
||||
}
|
||||
}
|
||||
if ($request->{'_disparatetftp'}->[0]) {
|
||||
$sub_req->({ command => ['makedhcp'], arg => ['-d', '-l'], node => \@rmdhcp_nodes }, $callback);
|
||||
$sub_req->({ command => ['makedhcp'],
|
||||
arg => \@parameter,
|
||||
node => \@normalnodeset }, $callback);
|
||||
} else {
|
||||
$sub_req->({ command => ['makedhcp'], arg => ['-d'], node => \@rmdhcp_nodes }, $callback);
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: dhcpsetup=$do_dhcpsetup");
|
||||
}
|
||||
}
|
||||
|
||||
@ -866,20 +759,16 @@ 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", "grub2: 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", "grub2: issue runendpre request");
|
||||
$sub_req->({ command => ['runendpre'],
|
||||
node => \@rnodes,
|
||||
node => \@normalnodeset,
|
||||
arg => [ $args[0] ] }, \&pass_along);
|
||||
}
|
||||
if ($errored) {
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed in running end prescripts\n";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Failed in running end prescripts.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,8 +89,7 @@ sub setstate {
|
||||
my $tftpdir = shift;
|
||||
my %nrhash = %{ shift() };
|
||||
my $linuximghash = shift();
|
||||
my $kern = $bphash{$node}->[0]; #$bptab->getNodeAttribs($node,['kernel','initrd','kcmdline']);
|
||||
#my $nodereshash=$noderestab->getNodesAttribs(\@nodes,['tftpdir','xcatmaster','nfsserver', 'servicenode']);
|
||||
my $kern = $bphash{$node}->[0];
|
||||
|
||||
if ($kern->{kernel} !~ /^$tftpdir/) {
|
||||
my $nodereshash = $nrhash{$node}->[0];
|
||||
@ -110,12 +109,7 @@ sub setstate {
|
||||
my @ipfnd = xCAT::NetworkUtils->my_ip_facing($node);
|
||||
|
||||
if ($ipfnd[0] == 1) {
|
||||
$::callback->(
|
||||
{
|
||||
error => [ $ipfnd[1] ],
|
||||
errorcode => [1]
|
||||
});
|
||||
return;
|
||||
return (1, $ipfnd[1]);
|
||||
}
|
||||
elsif ($ipfnd[0] == 2) {
|
||||
my $servicenodes = $nrhash{$node}->[0];
|
||||
@ -125,27 +119,11 @@ sub setstate {
|
||||
|
||||
# We are in the service node pools, print error if no facing ip.
|
||||
if (xCAT::InstUtils->is_me($sn)) {
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$::myxcatname: $ipfnd[1] on service node $sn"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
return;
|
||||
return (1, "$::myxcatname: $ipfnd[1] on service node $sn");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$::callback->(
|
||||
{
|
||||
error => [
|
||||
"$::myxcatname: $ipfnd[1]"
|
||||
],
|
||||
errorcode => [1]
|
||||
}
|
||||
);
|
||||
return;
|
||||
return (1, "$::myxcatname: $ipfnd[1]");
|
||||
}
|
||||
} else {
|
||||
$ipfn = $ipfnd[1];
|
||||
@ -172,9 +150,11 @@ sub setstate {
|
||||
unless (-d "$bootloader_root") {
|
||||
mkpath("$bootloader_root");
|
||||
}
|
||||
my $nodemac;
|
||||
|
||||
my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']);
|
||||
my $cref = $chainhash{$node}->[0];
|
||||
unless ($cref->{currstate}) { # the currstate should be set during 'setdestiny'
|
||||
return (1, "Cannot determine current state for this node");
|
||||
}
|
||||
|
||||
my $pcfg;
|
||||
# remove the old boot configuration file and create a new one, but only if not offline directive
|
||||
@ -183,21 +163,8 @@ sub setstate {
|
||||
open($pcfg, '>', "$bootloader_root/" . $node);
|
||||
print $pcfg "#" . $cref->{currstate} . "\n";
|
||||
}
|
||||
$normalnodes{$node} = 1; #Assume a normal netboot (well, normal dhcp,
|
||||
#which is normally with a valid 'filename' field,
|
||||
#but the typical ppc case will be 'special' makedhcp
|
||||
#to clear the filename field, so the logic is a little
|
||||
#opposite
|
||||
# $sub_req->({command=>['makedhcp'], #This is currently batched elswhere
|
||||
# node=>[$node]},$callback); #It hopefully will perform correctly
|
||||
|
||||
if ($cref and $cref->{currstate} eq "boot") {
|
||||
$breaknetbootnodes{$node} = 1;
|
||||
delete $normalnodes{$node}; #Signify to omit this from one makedhcp command
|
||||
#$sub_req->({command=>['makedhcp'], #batched elsewhere, this code is stale, hopefully
|
||||
# node=>[$node],
|
||||
# arg=>['-s','filename = \"xcat/nonexistant_file_to_intentionally_break_netboot_for_localboot_to_work\";']},$callback);
|
||||
#print $pcfg "bye\n";
|
||||
close($pcfg);
|
||||
} elsif ($kern and $kern->{kernel} and $cref and $cref->{currstate} ne "offline") {
|
||||
|
||||
@ -222,8 +189,7 @@ sub setstate {
|
||||
}
|
||||
my $ip = xCAT::NetworkUtils->getipaddr($node);
|
||||
unless ($ip) {
|
||||
syslog("local1|err", "xCAT unable to resolve IP for $node in petitboot plugin");
|
||||
return;
|
||||
return (1, "xCAT unable to resolve IP for $node in petitboot plugin.");
|
||||
}
|
||||
|
||||
my @ipa = split(/\./, $ip);
|
||||
@ -235,30 +201,44 @@ sub setstate {
|
||||
if ($cref and $cref->{currstate} ne "offline") {
|
||||
link("$bootloader_root/" . $node, "$tftpdir/" . $pname);
|
||||
}
|
||||
return;
|
||||
return (0, "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
$callback->($resp);
|
||||
|
||||
if ($failure > 1) { # quick abort
|
||||
$errored = $failure;
|
||||
return;
|
||||
}
|
||||
|
||||
# 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub preprocess_request {
|
||||
my $req = shift;
|
||||
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
||||
@ -407,8 +387,8 @@ sub process_request {
|
||||
$::callback = $callback;
|
||||
$sub_req = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
%breaknetbootnodes = ();
|
||||
%normalnodes = (); # It will be fill-up by method: setstate.
|
||||
|
||||
undef %failurenodes;
|
||||
|
||||
#>>>>>>>used for trace log start>>>>>>>
|
||||
my @args = ();
|
||||
@ -464,7 +444,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,11 +530,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.\n";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Failed in running begin prescripts.");
|
||||
return if ($errored > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,8 +551,8 @@ sub process_request {
|
||||
bootparams => \%bphash},
|
||||
\&pass_along);
|
||||
if ($errored) {
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Failed in processing setdestiny. Processing will not continue.");
|
||||
return;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Failed in processing setdestiny.");
|
||||
return if ($errored > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,7 +565,7 @@ sub process_request {
|
||||
#this does not hurt anything for other plugins
|
||||
environment => {XCAT_OPENBMC_DEVEL=>"YES"}
|
||||
});
|
||||
xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: clear node(s): @nodes boot device setting.");
|
||||
xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: clear node(s): $str_node boot device setting.");
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: starting to handle configuration...");
|
||||
@ -597,24 +573,25 @@ sub process_request {
|
||||
my $chainhash = $chaintab->getNodesAttribs(\@nodes, ['currstate']);
|
||||
my $noderestab = xCAT::Table->new('noderes', -create => 1);
|
||||
my $nodereshash = $noderestab->getNodesAttribs(\@nodes, [ 'tftpdir', 'xcatmaster', 'nfsserver', 'servicenode' ]);
|
||||
my $mactab = xCAT::Table->new('mac', -create => 1);
|
||||
my $machash = $mactab->getNodesAttribs(\@nodes, ['mac']);
|
||||
my $typetab = xCAT::Table->new('nodetype', -create => 1);
|
||||
my $typehash = $typetab->getNodesAttribs(\@nodes, [ 'os', 'provmethod', 'arch', 'profile' ]);
|
||||
my $linuximgtab = xCAT::Table->new('linuximage', -create => 1);
|
||||
my $osimagetab = xCAT::Table->new('osimage', -create => 1);
|
||||
my %machash = ();
|
||||
|
||||
my $rc;
|
||||
my $errstr;
|
||||
|
||||
my $tftpdir;
|
||||
my @normalnodeset = ();
|
||||
foreach (@nodes) {
|
||||
my %response;
|
||||
next if (exists($failurenodes{$_}));
|
||||
|
||||
my $tftpdir = $globaltftpdir;
|
||||
if ($nodereshash->{$_} and $nodereshash->{$_}->[0] and $nodereshash->{$_}->[0]->{tftpdir}) {
|
||||
$tftpdir = $nodereshash->{$_}->[0]->{tftpdir};
|
||||
} else {
|
||||
$tftpdir = $globaltftpdir;
|
||||
}
|
||||
|
||||
my %response;
|
||||
$response{node}->[0]->{name}->[0] = $_;
|
||||
if ($args[0]) { # send it on to the destiny plugin, then setstate
|
||||
my $ent = $typehash->{$_}->[0];
|
||||
@ -625,24 +602,16 @@ sub process_request {
|
||||
($rc, $errstr) = setstate($_, \%bphash, $chainhash, $machash, $tftpdir, $nodereshash, $linuximghash);
|
||||
if ($rc) {
|
||||
$response{node}->[0]->{errorcode}->[0] = $rc;
|
||||
$response{node}->[0]->{errorc}->[0] = $errstr;
|
||||
$response{node}->[0]->{error}->[0] = $errstr;
|
||||
$failurenodes{$_} = 1;
|
||||
$callback->(\%response);
|
||||
} else {
|
||||
push @normalnodeset, $_;
|
||||
}
|
||||
}
|
||||
} # end of foreach node
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Finish to handle configurations");
|
||||
|
||||
my @normalnodeset = keys %normalnodes;
|
||||
my @breaknetboot = keys %breaknetbootnodes;
|
||||
my %osimagenodehash;
|
||||
for my $nn (@normalnodeset) {
|
||||
|
||||
#record the os version for node
|
||||
my $ent = $typehash->{$nn}->[0];
|
||||
my $osimage = $ent->{'provmethod'};
|
||||
push @{ $osimagenodehash{$osimage} }, $nn;
|
||||
}
|
||||
|
||||
#Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time
|
||||
unless ($inittime) {
|
||||
|
||||
@ -675,20 +644,16 @@ 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) {
|
||||
my $rsp;
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{error}->[0] = "Failed in running end prescripts\n";
|
||||
$callback->($rsp);
|
||||
return;
|
||||
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Failed in running end prescripts.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,10 +185,28 @@ 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']);
|
||||
unless ($cref->{currstate}) { # the currstate should be set during 'setdestiny'
|
||||
return (1, "Cannot determine current state for this node");
|
||||
}
|
||||
|
||||
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 +302,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 +442,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 +494,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 +546,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 +632,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 +668,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 +677,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 +690,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 +711,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]->{error}->[0] = $errstr;
|
||||
$failurenodes{$_} = 1;
|
||||
$::XNBA_callback->(\%response);
|
||||
} else {
|
||||
push @normalnodeset, $_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -712,7 +740,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 +752,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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user