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

Merge pull request #1394 from gurevichmark/nodeset_offline

Nodeset offline for ppc64
This commit is contained in:
Xiaopeng Wang
2016-07-13 09:37:28 +08:00
committed by GitHub
6 changed files with 143 additions and 124 deletions

View File

@ -19,7 +19,7 @@ Name
****************
\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ | \ **iscsiboot**\ | \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ]
\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ | \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ]
\ **nodeset**\ \ *noderange*\ \ **osimage**\ [=\ *imagename*\ ] [\ **-**\ **-noupdateinitrd**\ ] [\ **-**\ **-ignorekernelchk**\ ]
@ -50,7 +50,7 @@ Assume that /tftpboot is the root for tftpd (set in site(5)|site.5).
\ **nodeset**\ only sets the next boot state, but does not reboot.
\ **nodeset**\ is called by rinstall and winstall and is also called by the
\ **nodeset**\ is called by \ **rinstall**\ and \ **winstall**\ and is also called by the
installation process remotely to set the boot state back to "boot".
A user can supply their own scripts to be run on the mn or on the service node (if a hierarchical cluster) for a node when the nodeset command is run. Such scripts are called \ **prescripts**\ . They should be copied to /install/prescripts dirctory. A table called \ *prescripts*\ is used to specify the scripts and their associated actions. The scripts to be run at the beginning of the nodeset command are stored in the 'begin' column of \ *prescripts*\ table. The scripts to be run at the end of the nodeset command are stored in the 'end' column of \ *prescripts*\ table. You can run 'tabdump -d prescripts' command for details. The following two environment variables will be passed to each script: NODES contains all the names of the nodes that need to run the script for and ACTION contains the current nodeset action. If \ *#xCAT setting:MAX_INSTANCE=number*\ is specified in the script, the script will get invoked for each node in parallel, but no more than \ *number*\ of instances will be invoked at at a time. If it is not specified, the script will be invoked once for all the nodes.
@ -82,8 +82,8 @@ A user can supply their own scripts to be run on the mn or on the service node (
\ **-**\ **-noupdateinitrd**\
Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drviers to initrd. But, the geninitrd command
should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of nodeset command.
Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drivers to initrd. But, the \ **geninitrd**\ command
should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of \ **nodeset**\ command.

View File

@ -461,7 +461,7 @@ Options:
"Usage:
Common:
nodeset [-h|--help|-v|--version]
nodeset <noderange> [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=<imagename>]|offline|shutdown|stat]",
nodeset <noderange> [shell|boot|runcmd=bmcsetup|osimage[=<imagename>]|offline|shutdown|stat]",
"rmflexnode" =>
"Usage:
rmflexnode [-h|--help|-v|--version]

View File

@ -4,7 +4,7 @@ B<nodeset> - set the boot state for a noderange
=head1 B<Synopsis>
B<nodeset> I<noderange> [B<boot> | B<stat> | B<iscsiboot> | B<offline> | B<runcmd=bmcsetup> | B<osimage>[=I<imagename>] | B<shell> | B<shutdown>]
B<nodeset> I<noderange> [B<boot> | B<stat> | B<offline> | B<runcmd=bmcsetup> | B<osimage>[=I<imagename>] | B<shell> | B<shutdown>]
B<nodeset> I<noderange> B<osimage>[=I<imagename>] [B<--noupdateinitrd>] [B<--ignorekernelchk>]
@ -31,7 +31,7 @@ B<nodeset> for yaboot makes changes to /tftpboot/etc/{node hex ip}
B<nodeset> only sets the next boot state, but does not reboot.
B<nodeset> is called by rinstall and winstall and is also called by the
B<nodeset> is called by B<rinstall> and B<winstall> and is also called by the
installation process remotely to set the boot state back to "boot".
A user can supply their own scripts to be run on the mn or on the service node (if a hierarchical cluster) for a node when the nodeset command is run. Such scripts are called B<prescripts>. They should be copied to /install/prescripts dirctory. A table called I<prescripts> is used to specify the scripts and their associated actions. The scripts to be run at the beginning of the nodeset command are stored in the 'begin' column of I<prescripts> table. The scripts to be run at the end of the nodeset command are stored in the 'end' column of I<prescripts> table. You can run 'tabdump -d prescripts' command for details. The following two environment variables will be passed to each script: NODES contains all the names of the nodes that need to run the script for and ACTION contains the current nodeset action. If I<#xCAT setting:MAX_INSTANCE=number> is specified in the script, the script will get invoked for each node in parallel, but no more than I<number> of instances will be invoked at at a time. If it is not specified, the script will be invoked once for all the nodes.
@ -55,8 +55,8 @@ Prepare server for installing a node using the specified os image. The os image
=item B<--noupdateinitrd>
Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drviers to initrd. But, the geninitrd command
should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of nodeset command.
Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drivers to initrd. But, the B<geninitrd> command
should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of B<nodeset> command.
=item B<--ignorekernelchk>

View File

@ -23,7 +23,7 @@ my $globaltftpdir = xCAT::TableUtils->getTftpDir();
my %usage = (
"nodeset" => "Usage: nodeset <noderange> [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=<imagename>]|offline|shutdown|stat]",
"nodeset" => "Usage: nodeset <noderange> [shell|boot|runcmd=bmcsetup|osimage[=<imagename>]|offline|shutdown|stat]",
);
sub handled_commands {
@ -78,7 +78,8 @@ sub getstate {
chomp($headline);
return $headline;
} else {
return "boot";
# There is no boot configuration file, node must be offline
return "offline";
}
} else {
return "discover";
@ -181,19 +182,21 @@ sub setstate {
my $nodemac;
my %client_nethash = xCAT::DBobjUtils->getNetwkInfo([$node]);
open($pcfg, '>', $tftpdir . "/boot/grub2/" . $node);
my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']);
if ($cref->{currstate}) {
# remove the old boot configuration file and create a new one, but only if not offline directive
unlink($tftpdir . "/boot/grub2/" . $node);
if ($cref and $cref->{currstate} ne "offline") {
open($pcfg, '>', $tftpdir . "/boot/grub2/" . $node);
print $pcfg "#" . $cref->{currstate} . "\n";
if (($::XCATSITEVALS{xcatdebugmode} eq "1") or ($::XCATSITEVALS{xcatdebugmode} eq "2")) {
print $pcfg "set debug=all\n";
}
print $pcfg "set timeout=5\n";
}
if (($::XCATSITEVALS{xcatdebugmode} eq "1") or ($::XCATSITEVALS{xcatdebugmode} eq "2")) {
print $pcfg "set debug=all\n";
}
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
@ -247,32 +250,34 @@ sub setstate {
return;
}
# write entries to boot config file, but only if not offline directive
if ($cref and $cref->{currstate} ne "offline") {
print $pcfg "set default=\"xCAT OS Deployment\"\n";
print $pcfg "menuentry \"xCAT OS Deployment\" {\n";
print $pcfg " insmod http\n";
print $pcfg " insmod tftp\n";
print $pcfg " set root=$grub2protocol,$serverip\n";
print $pcfg " echo Loading Install kernel ...\n";
print $pcfg "set default=\"xCAT OS Deployment\"\n";
print $pcfg "menuentry \"xCAT OS Deployment\" {\n";
print $pcfg " insmod http\n";
print $pcfg " insmod tftp\n";
print $pcfg " set root=$grub2protocol,$serverip\n";
print $pcfg " echo Loading Install kernel ...\n";
my $protocolrootdir = "";
if ($grub2protocol =~ /^http$/)
{
$protocolrootdir = $tftpdir;
}
my $protocolrootdir = "";
if ($grub2protocol =~ /^http$/)
{
$protocolrootdir = $tftpdir;
if ($kern and $kern->{kcmdline}) {
print $pcfg " linux $protocolrootdir/$kern->{kernel} $kern->{kcmdline}\n";
} else {
print $pcfg " linux $protocolrootdir/$kern->{kernel}\n";
}
print $pcfg " echo Loading initial ramdisk ...\n";
if ($kern and $kern->{initrd}) {
print $pcfg " initrd $protocolrootdir/$kern->{initrd}\n";
}
print $pcfg "}";
close($pcfg);
}
if ($kern and $kern->{kcmdline}) {
print $pcfg " linux $protocolrootdir/$kern->{kernel} $kern->{kcmdline}\n";
} else {
print $pcfg " linux $protocolrootdir/$kern->{kernel}\n";
}
print $pcfg " echo Loading initial ramdisk ...\n";
if ($kern and $kern->{initrd}) {
print $pcfg " initrd $protocolrootdir/$kern->{initrd}\n";
}
print $pcfg "}";
close($pcfg);
my $inetn = xCAT::NetworkUtils->getipaddr($node);
unless ($inetn) {
syslog("local1|err", "xCAT unable to resolve IP for $node in grub2 plugin");
@ -312,8 +317,11 @@ sub setstate {
foreach $ip (keys %ipaddrs) {
my @ipa = split(/\./, $ip);
my $pname = "grub.cfg-" . sprintf("%02x%02x%02x%02x", @ipa);
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
unlink($tftpdir . "/boot/grub2/" . $pname);
link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname);
if ($cref and $cref->{currstate} ne "offline") {
link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname);
}
}
if ($macstring) {
$nodemac = xCAT::Utils->parseMacTabEntry($macstring, $node);
@ -323,8 +331,11 @@ sub setstate {
my $tmp = lc($nodemac);
$tmp =~ s/(..):(..):(..):(..):(..):(..)/$1-$2-$3-$4-$5-$6/g;
my $pname = "grub.cfg-01-" . $tmp;
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
unlink($tftpdir . "/boot/grub2/" . $pname);
link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname);
if ($cref and $cref->{currstate} ne "offline") {
link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname);
}
}
return;
}
@ -713,6 +724,18 @@ sub process_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);
}
}
$sub_req->({ command => ['makedhcp'],arg=>['-d'], node => \@rmdhcp_nodes }, $callback);
}
#now run the end part of the prescripts
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact')
$errored = 0;

View File

@ -63,7 +63,8 @@ sub getstate {
chomp($headline);
return $headline;
} else {
return "boot";
# There is no boot configuration file, node must be offline
return "offline";
}
} else {
return "discover";
@ -168,10 +169,13 @@ sub setstate {
}
my $nodemac;
open($pcfg,'>',$tftpdir."/petitboot/".$node);
my $cref=$chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']);
if ($cref->{currstate}) {
print $pcfg "#".$cref->{currstate}."\n";
# remove the old boot configuration file and create a new one, but only if not offline directive
unlink($tftpdir . "/petitboot/" . $node);
if ($cref and $cref->{currstate} ne "offline") {
open($pcfg,'>',$tftpdir."/petitboot/".$node);
print $pcfg "#".$cref->{currstate}."\n";
}
$normalnodes{$node}=1; #Assume a normal netboot (well, normal dhcp,
#which is normally with a valid 'filename' field,
@ -181,45 +185,48 @@ sub setstate {
# $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}) {
#It's time to set yaboot for this node to boot the kernel..
print $pcfg "default xCAT\n";
print $pcfg "label xCAT\n";
print $pcfg "\tkernel $kern->{kernel}\n";
if ($kern and $kern->{initrd}) {
print $pcfg "\tinitrd ".$kern->{initrd}."\n";
}
if ($kern and $kern->{kcmdline}) {
print $pcfg "\tappend \"".$kern->{kcmdline}."\"\n";
}
close($pcfg);
my $inetn = xCAT::NetworkUtils->getipaddr($node);
unless ($inetn) {
syslog("local1|err","xCAT unable to resolve IP for $node in petitboot plugin");
return;
}
$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") {
#It's time to set petitboot for this node to boot the kernel, but only if not offline directive
print $pcfg "default xCAT\n";
print $pcfg "label xCAT\n";
print $pcfg "\tkernel $kern->{kernel}\n";
if ($kern and $kern->{initrd}) {
print $pcfg "\tinitrd ".$kern->{initrd}."\n";
}
if ($kern and $kern->{kcmdline}) {
print $pcfg "\tappend \"".$kern->{kcmdline}."\"\n";
}
close($pcfg);
my $inetn = xCAT::NetworkUtils->getipaddr($node);
unless ($inetn) {
syslog("local1|err","xCAT unable to resolve IP for $node in petitboot plugin");
return;
}
} else { #TODO: actually, should possibly default to xCAT image?
#print $pcfg "bye\n";
close($pcfg);
#print $pcfg "bye\n";
close($pcfg);
}
my $ip = xCAT::NetworkUtils->getipaddr($node);
unless ($ip) {
syslog("local1|err","xCAT unable to resolve IP in petitboot plugin");
return;
syslog("local1|err","xCAT unable to resolve IP in petitboot plugin");
return;
}
my @ipa=split(/\./,$ip);
my $pname = sprintf("%02x%02x%02x%02x",@ipa);
$pname = uc($pname);
unlink($tftpdir."/".$pname);
my @ipa=split(/\./,$ip);
my $pname = sprintf("%02x%02x%02x%02x",@ipa);
$pname = uc($pname);
# remove the old boot configuration file and copy (link) a new one, but only if not offline directive
unlink($tftpdir."/".$pname);
if ($cref and $cref->{currstate} ne "offline") {
link($tftpdir."/petitboot/".$node,$tftpdir."/".$pname);
}
return;
}
@ -473,29 +480,29 @@ sub process_request {
my $tftpdir;
foreach (@nodes) {
my %response;
if ($nodereshash->{$_} and $nodereshash->{$_}->[0] and $nodereshash->{$_}->[0]->{tftpdir}) {
$tftpdir = $nodereshash->{$_}->[0]->{tftpdir};
} else {
$tftpdir = $globaltftpdir;
}
$response{node}->[0]->{name}->[0]=$_;
if ($args[0] eq 'stat') {
$response{node}->[0]->{data}->[0]= getstate($_,$tftpdir);
$callback->(\%response);
} elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate
my $ent = $typehash->{$_}->[0];
my $osimgname = $ent->{'provmethod'};
my $linuximghash = $linuximghash = $linuximgtab->getAttribs({imagename => $osimgname}, 'boottarget', 'addkcmdline');
my %response;
if ($nodereshash->{$_} and $nodereshash->{$_}->[0] and $nodereshash->{$_}->[0]->{tftpdir}) {
$tftpdir = $nodereshash->{$_}->[0]->{tftpdir};
} else {
$tftpdir = $globaltftpdir;
}
$response{node}->[0]->{name}->[0]=$_;
if ($args[0] eq 'stat') {
$response{node}->[0]->{data}->[0]= getstate($_,$tftpdir);
$callback->(\%response);
} elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate
my $ent = $typehash->{$_}->[0];
my $osimgname = $ent->{'provmethod'};
my $linuximghash = $linuximghash = $linuximgtab->getAttribs({imagename => $osimgname}, 'boottarget', 'addkcmdline');
($rc,$errstr) = setstate($_,$bphash,$chainhash,$machash,$tftpdir,$nodereshash,$linuximghash);
if ($rc) {
$response{node}->[0]->{errorcode}->[0]= $rc;
$response{node}->[0]->{errorc}->[0]= $errstr;
$callback->(\%response);
($rc,$errstr) = setstate($_,$bphash,$chainhash,$machash,$tftpdir,$nodereshash,$linuximghash);
if ($rc) {
$response{node}->[0]->{errorcode}->[0]= $rc;
$response{node}->[0]->{errorc}->[0]= $errstr;
$callback->(\%response);
}
}
}
}# end of foreach node
my @normalnodeset = keys %normalnodes;
@ -535,6 +542,11 @@ sub process_request {
}
}
}
if ($args[0] eq 'offline') {
# If nodeset directive was offline we need to remove dhcp entries
$sub_req->({ command => ['makedhcp'],arg=>['-d'], node => \@normalnodeset }, $callback);
}
#now run the end part of the prescripts
unless ($args[0] eq 'stat') { # or $args[0] eq 'enact')
@ -560,27 +572,6 @@ sub process_request {
}
}
sub getstate {
my $node = shift;
my $tftpdir = shift;
unless ($tftpdir) { $tftpdir = _slow_get_tftpdir($node); }
if (check_dhcp($node)) {
if (-r $tftpdir . "/petitboot/".$node) {
my $fhand;
open ($fhand,$tftpdir . "/petitboot/".$node);
my $headline = <$fhand>;
close $fhand;
$headline =~ s/^#//;
chomp($headline);
return $headline;
} else {
return "boot";
}
} else {
return "discover";
}
}
#----------------------------------------------------------------------------
=head3 getNodesetStates
returns the nodeset state for the given nodes. The possible nodeset

View File

@ -18,7 +18,7 @@ my $globaltftpdir = xCAT::TableUtils->getTftpDir();
#my $dhcpver = 3;
my %usage = (
"nodeset" => "Usage: nodeset <noderange> [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=<imagename>]|offline]",
"nodeset" => "Usage: nodeset <noderange> [shell|boot|runcmd=bmcsetup|osimage[=<imagename>]|offline]",
);
sub handled_commands {
return {
@ -76,7 +76,8 @@ sub getstate {
chomp($headline);
return $headline;
} else {
return "boot";
# There is no boot configuration file, node must be offline
return "offline";
}
} else {
return "discover";
@ -568,6 +569,10 @@ sub process_request {
}
}
}
# for offline operation, remove the dhcp entries
if ($args[0] eq 'offline') {
$sub_req->({ command => ['makedhcp'],arg=>['-d'],node => \@nodes }, $::XNBA_callback);
}
#dhcp stuff -- inittime is set when xcatd on sn is started