diff --git a/makexcatrpm b/makexcatrpm index 495fbf58e..afc8b8f53 100755 --- a/makexcatrpm +++ b/makexcatrpm @@ -35,6 +35,7 @@ else cd `dirname $0`/xCAT tar --exclude .svn -czf /usr/src/$pkg/SOURCES/postscripts.tar.gz postscripts LICENSE.html + tar --exclude .svn -czf /usr/src/$pkg/SOURCES/prescripts.tar.gz prescripts tar --exclude .svn -czf /usr/src/$pkg/SOURCES/templates.tar.gz templates cp xcat.conf /usr/src/$pkg/SOURCES cd - diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index e071b437c..031997d68 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -321,7 +321,7 @@ nodelist => { descriptions => { node => 'The hostname of a node in the cluster.', groups => "A comma-delimited list of groups this node is a member of. Group names are arbitrary, except all nodes should be part of the 'all' group.", - status => 'The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. The default value is defined. The possible status change sequenses are: defined->[discovering]->[configuring]->[standingby]->installing->[installed]->booting->alive, defined->[discovering]->[configuring]->[standingby]->netbooting->booted->alive, alive/unreachable->booting->alive, alive->powering-off->unreachable, alive->unreachable', + status => 'The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. If blank, defined is assumed. The possible status change sequenses are: For installaton: defined->[discovering]->[configuring]->[standingby]->installing->[installed]->booting->[alive], For diskless deployment: defined->[discovering]->[configuring]->[standingby]->netbooting->booted->[alive], For booting: [alive/unreachable]->booting->[alive], For powering off: [alive]->powering-off->[unreachable], For monitoring: alive->unreachable. Discovering and configuring are for x Series dicovery process. Alive and unreachable are set only when there is a monitoring plug-in start monitor the node status for xCAT.', appstatus => "A comma-delimited list monitored applications that are active on the node. For example 'sshd,rmcd,gmond", primarysn => "Not used currently. The primary servicenode, used by this node.", comments => 'Any user-written notes.', @@ -662,6 +662,29 @@ eventlog => { disable => "Set to 'yes' or '1' to comment out this row.", }, }, +prescripts => { + cols => [qw(node begin end comments disable)], + keys => [qw(node)], + table_desc => 'The scripts that should be run at the beginning and the end of the nodeset or nimnodeset/mkdsklsnode (AIX) command.', + descriptions => { + node => 'The node name or group name.', + begin => +"The scripts to be run at the beginning of the nodeset (Linux) or nimnodeset/mkdsklsnode (AIX) command.\n". +"\t\tThe format is:\n". +"\t\t[action1:]s1,s2...[|action2:s3,s4,s5...]\n". +"\t\twhere action1 and action2 are the nodeset/nimnodeset actions specified in the command.\n". +"\t\ts1 and s2 are the scripts to run for action1 in order. s3,s4,and s5 are the scripts\n". +"\t\tto run for actions2. If actions are omitted, the scripts apply to all actions.\n". +"\t\tExamples:\n". +"\t\tmyscript1,myscript2\n". +"\t\tinstall:myscript1,myscript2|netboot:myscript3", + end => +"The scripts to be run at the end of the nodeset (Linux) or nimnodeset/mkdsklsnode (AIX) command.\n" . +"\t\tThe format is the same as the 'begin' column.", + comments => 'Any user-written notes.', + disable => "Set to 'yes' or '1' to comment out this row.", + }, +}, ); # end of tabspec definition @@ -1268,6 +1291,17 @@ my @nodeattrs = ( tabentry => 'nodelist.comments', access_tabentry => 'nodelist.node=attr:node', }, +#################### +# prescripts table# +#################### + {attr_name => 'prescripts-begin', + tabentry => 'prescripts.begin', + access_tabentry => 'prescripts.node=attr:node', + }, + {attr_name => 'prescripts-end', + tabentry => 'prescripts.end', + access_tabentry => 'prescripts.node=attr:node', + }, ); # add on the node attrs from other tables diff --git a/xCAT-server/lib/xcat/plugins/prescripts.pm b/xCAT-server/lib/xcat/plugins/prescripts.pm new file mode 100644 index 000000000..f65c4bd3a --- /dev/null +++ b/xCAT-server/lib/xcat/plugins/prescripts.pm @@ -0,0 +1,356 @@ +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT_plugin::prescripts; +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; +use strict; +require xCAT::Table; +require xCAT::Utils; +require xCAT::MsgUtils; +use Getopt::Long; +use Sys::Hostname; +1; + +#------------------------------------------------------- +=head3 handled_commands +Return list of commands handled by this plugin +=cut +#------------------------------------------------------- + +sub handled_commands +{ + return { + runbeginpre => "prescripts", + runendpre => "prescripts" + }; +} + +#------------------------------------------------------- +=head3 preprocess_request + Check and setup for hierarchy +=cut +#------------------------------------------------------- +sub preprocess_request +{ + my $req = shift; + my $cb = shift; + + #if already preprocessed, go straight to request + if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; } + + my $nodes = $req->{node}; + if (!$nodes) { return;} + + my $service = "xcat"; + my @args=(); + if (ref($req->{arg})) { + @args=@{$req->{arg}}; + } else { + @args=($req->{arg}); + } + @ARGV = @args; + + print "prepscripts: preprocess_request get called, args=@args, nodes=@$nodes\n"; + + #use Getopt::Long; + Getopt::Long::Configure("bundling"); + Getopt::Long::Configure("pass_through"); + GetOptions('l' => \$::LOCAL); + my $sn = xCAT::Utils->get_ServiceNode($nodes, $service, "MN"); + my @requests; + if ($::LOCAL) { #only handle the local nodes + print "process local nodes: @$nodes\n"; + #get its own children only + my @hostinfo=xCAT::Utils->determinehostname(); + my %iphash=(); + foreach(@hostinfo) {$iphash{$_}=1;} + + my @children=(); + foreach my $snkey (keys %$sn) { + if (exists($iphash{$snkey})) { + my $tmp=$sn->{$snkey}; + @children=(@children,@$tmp); + } + } + if (@children > 0) { + my $reqcopy = {%$req}; + $reqcopy->{node} = \@children; + $reqcopy->{'_xcatdest'} = $hostinfo[0]; + $reqcopy->{_xcatpreprocessed}->[0] = 1; + push @requests, $reqcopy; + return \@requests; + } + } else { #run on mn and need to dispatch the requests to the service nodes + print "dispatch to sn\n"; + # find service nodes for requested nodes + # build an individual request for each service node + # find out the names for the Management Node + foreach my $snkey (keys %$sn) + { + print "sn=$snkey\n"; + my $reqcopy = {%$req}; + $reqcopy->{node} = $sn->{$snkey}; + $reqcopy->{'_xcatdest'} = $snkey; + $reqcopy->{_xcatpreprocessed}->[0] = 1; + push @requests, $reqcopy; + + } # end foreach + return \@requests; + } + return; +} + +#------------------------------------------------------- + +=head3 process_request + + Process the command + +=cut + +#------------------------------------------------------- +sub process_request +{ + my $request = shift; + my $callback = shift; + my $nodes = $request->{node}; + my $command = $request->{command}->[0]; + my $args = $request->{arg}; + my $rsp = {}; + + if ($command eq "runbeginpre") + { + runbeginpre($nodes, $request, $callback); + } + else + { + if ($command eq "runendpre") + { + runendpre($nodes, $request, $callback) + } + else + { + my $rsp = {}; + $rsp->{data}->[0] = + "Unknown command $command. Cannot process the command."; + xCAT::MsgUtils->message("E", $rsp, $callback, 1); + return; + } + } +} + +#------------------------------------------------------- +=head3 runbeginpre + Runs all the begin scripts defined in prescripts.begin column for the give nodes. +=cut +#------------------------------------------------------- +sub runbeginpre +{ + my ($nodes, $request, $callback) = @_; + my $args = $request->{arg}; + my $action=$args->[0]; + my $localhostname=hostname(); + my $installdir = "/install"; # default + my @installdir1 = xCAT::Utils->get_site_attribute("installdir"); + if ($installdir1[0]) + { + $installdir = $installdir1[0]; + } + + my %script_hash=getprescripts($nodes, $action, "begin"); + foreach my $scripts (keys %script_hash) { + my $runnodes=$script_hash{$scripts}; + if ($runnodes && (@$runnodes>0)) { + my $runnodes_s=join(',', @$runnodes); + my $rsp = {}; + $rsp->{data}->[0]="$localhostname: Running $scripts for nodes $runnodes_s."; + $callback->($rsp); + + #now run the scripts + undef $SIG{CHLD}; + my @script_array=split(',', $scripts); + foreach my $s (@script_array) { + my $ret=`NODES=$runnodes_s ACTION=$action $installdir/prescripts/$s 2>&1`; + my $err_code=$?; + if ($err_code != 0) { + my $rsp = {}; + $rsp->{data}->[0]="$localhostname: $err_code: $ret"; + $callback->($rsp); + last; + } + } + } + } + return; +} + +#------------------------------------------------------- +=head3 runendpre + Runs all the begin scripts defined in prescripts.begin column for the give nodes. +=cut +#------------------------------------------------------- +sub runendpre +{ + my ($nodes, $request, $callback) = @_; + + my $args= $request->{arg}; + my $action=$args->[0]; + my $localhostname=hostname(); + my $installdir = "/install"; # default + my @installdir1 = xCAT::Utils->get_site_attribute("installdir"); + if ($installdir1[0]) + { + $installdir = $installdir1[0]; + } + my $inittime=0; + if (exists($request->{inittime})) { $inittime=$request->{inittime}->[0];} + if (!$inittime) { $inittime=0; }; + + #normalnodeset and breaknetboot are used by setupdhcp + #yaboo sets up normalnodeset and breaknetboot; pxe does not, so we use $nodes for pxe + my $normalnodeset=[]; + if (exists($request->{normalnodeset})) { $normalnodeset=$request->{normalnodeset};} + my $breaknetboot=[]; + if (exists($request->{breaknetboot})) { $breaknetboot=$request->{breaknetboot};} + if ((!$normalnodeset) && (!$breaknetboot)) { $normalnodeset=$nodes;} + + print "prescripts:inittime=$inittime; normalnodeset=@$normalnodeset; breaknetboot=@$breaknetboot\n"; + + my %script_hash=getprescripts($nodes, $action, "end"); + foreach my $scripts (keys %script_hash) { + my $runnodes=$script_hash{$scripts}; + if ($runnodes && (@$runnodes>0)) { + my $runnodes_s=join(',', @$runnodes); + my %runnodes_hash=(); + foreach (@$runnodes) { $runnodes_hash{$_}=1; } + + my $rsp = {}; + $rsp->{data}->[0]="$localhostname: Running $scripts for nodes $runnodes_s."; + $callback->($rsp); + + #now run the scripts + undef $SIG{CHLD}; + my @script_array=split(',', $scripts); + foreach my $s (@script_array) { + my $ret; + print "script name=$s\n"; + if ($s eq "setupdhcp") { #special case for setupdhcp + #remove the nodes from normalnodeset and breaknetboot that are not in runnodes + my @new_normalnodeset=(); + my @new_breaknetboot=(); + foreach (@$normalnodeset) { + if ($runnodes_hash{$_}) { push(@new_normalnodeset, $_); } + } + foreach (@$breaknetboot) { + if ($runnodes_hash{$_}) { push(@new_breaknetboot, $_); } + } + my $normalnodeset_s=join(',', @new_normalnodeset); + my $breaknetboot_s=join(',', @new_breaknetboot); + if (!$normalnodeset_s) { $normalnodeset_s="NONE"; } + if (!$breaknetboot_s) { $breaknetboot_s="NONE";} + + print "prescripts:inittime=$inittime; normalnodeset=$normalnodeset_s; breaknetboot=$breaknetboot_s\n"; + $ret=`NODES=$runnodes_s ACTION=$action $installdir/prescripts/$s $inittime $normalnodeset_s $breaknetboot_s 2>&1`; + } else { + $ret=`NODES=$runnodes_s ACTION=$action $installdir/prescripts/$s 2>&1`; + } + my $rsp = {}; + $rsp->{data}->[0]="$localhostname: $s: $ret"; + $callback->($rsp); + my $err_code=$?; + if ($err_code != 0) { + $rsp = {}; + $rsp->{data}->[0]="$localhostname: $s: error code=$err_code."; + $callback->($rsp); + last; + } + } + } + } + return; +} + +#------------------------------------------------------- +=head3 getprescripts + get the prescripts for the given nodes and actions +=cut +#------------------------------------------------------- +sub getprescripts +{ + my ($nodes, $action, $colname) = @_; + my %ret=(); + if ($nodes && (@$nodes>0)) { + my $tab = xCAT::Table->new('prescripts',-create=>1); + #first get xcatdefault column + my $et = $tab->getAttribs({node=>"xcatdefaults"},$colname); + my $tmp_def = $et->{$colname}; + my $defscripts; + if ($tmp_def) { + $defscripts=parseprescripts($tmp_def, $action); + } + + #get scripts for the given nodes and + #add the scripts from xcatdefault in front of the other scripts + my $tabdata=$tab->getNodesAttribs($nodes,['node', $colname]); + foreach my $node (@$nodes) { + my $scripts_to_save=$defscripts; + my %lookup=(); #so that we do not have to parse the same scripts more than once + if ($tabdata && exists($tabdata->{$node})) { + my $tmp=$tabdata->{$node}->[0]; + my $scripts=$tmp->{$colname}; + if ($scripts) { + #parse the script. it is in the format of netboot:s1,s2|install:s3,s4 or just s1,s2 + if (!exists($lookup{$scripts})) { + my $tmp_s=parseprescripts($scripts, $action); + $lookup{$scripts}=$tmp_s; + $scripts=$tmp_s; + } else { + $scripts=$lookup{$scripts}; + } + #add the xcatdefaults + if ($scripts_to_save && $scripts) { + $scripts_to_save .= ",$scripts"; + } else { + if ($scripts) { $scripts_to_save=$scripts; } + } + } + } + + #save to the hash + if ($scripts_to_save) { + if (exists($ret{$scripts_to_save})) { + my $pa=$ret{$scripts_to_save}; + push(@$pa, $node); + } + else { + $ret{$scripts_to_save}=[$node]; + } + } + } + } + return %ret; +} + +#------------------------------------------------------- +=head3 parseprescripts + Parse the prescript string and get the scripts for the given action out +=cut +#------------------------------------------------------- +sub parseprescripts +{ + my $scripts=shift; + my $action=shift; + my $ret; + if ($scripts) { + if ($scripts =~ /:/) { + if ($scripts =~ /$action:([^|]*)/) { + $ret=$1; + } + } else { + $ret=$scripts; + } + } + return $ret; +} diff --git a/xCAT-server/lib/xcat/plugins/pxe.pm b/xCAT-server/lib/xcat/plugins/pxe.pm index e2bbb5e82..9b2aa9834 100644 --- a/xCAT-server/lib/xcat/plugins/pxe.pm +++ b/xCAT-server/lib/xcat/plugins/pxe.pm @@ -5,6 +5,7 @@ use Sys::Syslog; use Socket; use File::Copy; use File::Path; +use Getopt::Long; my $request; my $callback; @@ -223,10 +224,76 @@ sub pass_along { sub preprocess_request { + my $req = shift; + if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; } + + $callback = shift; + my $command = $req->{command}->[0]; + my $sub_req = shift; + my @args=(); + if (ref($req->{arg})) { + @args=@{$req->{arg}}; + } else { + @args=($req->{arg}); + } + @ARGV = @args; + + #use Getopt::Long; + Getopt::Long::Configure("bundling"); + Getopt::Long::Configure("pass_through"); + if (!GetOptions('h|?|help' => \$HELP, 'v|version' => \$VERSION) ) { + if($usage{$command}) { + my %rsp; + $rsp{data}->[0]=$usage{$command}; + $callback->(\%rsp); + } + return; + } + + if ($HELP) { + if($usage{$command}) { + my %rsp; + $rsp{data}->[0]=$usage{$command}; + $callback->(\%rsp); + } + return; + } + + if ($VERSION) { + my $ver = xCAT::Utils->Version(); + my %rsp; + $rsp{data}->[0]="$ver"; + $callback->(\%rsp); + return; + } + + if (@ARGV==0) { + if($usage{$command}) { + my %rsp; + $rsp{data}->[0]=$usage{$command}; + $callback->(\%rsp); + } + return; + } + + #now run the begin part of the prescripts + #my @nodes=(); + #if (ref($req->{node})) { +# @nodes = @{$req->{node}}; +# } else { +# if ($req->{node}) { @nodes = ($req->{node}); } +# } +# $errored=0; +# unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { +# $sub_req->({command=>['runbeginpre'], +# node=>\@nodes, +# arg=>[$args[0]]},\&pass_along); +# } +# if ($errored) { return; } + #Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when #they specify no sharedtftp in site table my $stab = xCAT::Table->new('site'); - my $req = shift; my $sent = $stab->getAttribs({key=>'sharedtftp'},'value'); if ($sent and ($sent->{value} == 0 or $sent->{value} =~ /no/i)) { $req->{'_disparatetftp'}=[1]; @@ -304,15 +371,6 @@ sub process_request { if ($request->{node}) { @rnodes = ($request->{node}); } } - my $args_ref = $request->{arg}; - if(scalar grep(/^--version$|^-v$/, @$args_ref)) { - my $ver = xCAT::Utils->Version(); - my %rsp; - $rsp{data}->[0]="$ver"; - $callback->(\%rsp); - return; - } - unless (@rnodes) { if ($usage{$request->{command}->[0]}) { $callback->({data=>$usage{$request->{command}->[0]}}); @@ -385,15 +443,27 @@ sub process_request { } } } - if ($request->{inittime}->[0]) { return; } #Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time - if ($args[0] ne 'stat') { - if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command - $sub_req->({command=>['makedhcp'],arg=>['-l'], - node=>\@nodes},$callback); - } else { - $sub_req->({command=>['makedhcp'], - node=>\@nodes},$callback); - } + + my $inittime=0; + if (exists($request->{inittime})) { $inittime= $request->{inittime}->[0];} + if (!$inittime) { $inittime=0;} + #now run the end part of the prescripts + unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') + $errored=0; + if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children + $sub_req->({command=>['runendpre'], + node=>\@nodes, + inittime=>[$inittime], + normalnodeset=>\@nodes, + 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 + $sub_req->({command=>['runendpre'], + node=>\@rnodes, + normalnodeset=>\@nodes, + inittime=>[$inittime], + arg=>[$args[0]]},\&pass_along); + } + if ($errored) { return; } } } diff --git a/xCAT-server/lib/xcat/plugins/yaboot.pm b/xCAT-server/lib/xcat/plugins/yaboot.pm index 598afe672..10fc60b52 100644 --- a/xCAT-server/lib/xcat/plugins/yaboot.pm +++ b/xCAT-server/lib/xcat/plugins/yaboot.pm @@ -5,6 +5,7 @@ use Sys::Syslog; use xCAT::Scope; use File::Path; use Socket; +use Getopt::Long; my $request; my %breaknetbootnodes; @@ -187,6 +188,7 @@ sub setstate { my $errored = 0; sub pass_along { + print "pass_along\n"; my $resp = shift; $callback->($resp); if ($resp and ($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) { @@ -202,10 +204,76 @@ sub pass_along { sub preprocess_request { + my $req = shift; + if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; } + + $callback = shift; + my $command = $req->{command}->[0]; + my $sub_req = shift; + my @args=(); + if (ref($req->{arg})) { + @args=@{$req->{arg}}; + } else { + @args=($req->{arg}); + } + @ARGV = @args; + + #use Getopt::Long; + Getopt::Long::Configure("bundling"); + Getopt::Long::Configure("pass_through"); + if (!GetOptions('h|?|help' => \$HELP, 'v|version' => \$VERSION) ) { + if($usage{$command}) { + my %rsp; + $rsp{data}->[0]=$usage{$command}; + $callback->(\%rsp); + } + return; + } + + if ($HELP) { + if($usage{$command}) { + my %rsp; + $rsp{data}->[0]=$usage{$command}; + $callback->(\%rsp); + } + return; + } + + if ($VERSION) { + my $ver = xCAT::Utils->Version(); + my %rsp; + $rsp{data}->[0]="$ver"; + $callback->(\%rsp); + return; + } + + if (@ARGV==0) { + if($usage{$command}) { + my %rsp; + $rsp{data}->[0]=$usage{$command}; + $callback->(\%rsp); + } + return; + } + + #now run the begin part of the prescripts + #my @nodes=(); + #if (ref($req->{node})) { +# @nodes = @{$req->{node}}; +# } else { +# if ($req->{node}) { @nodes = ($req->{node}); } +# } +# $errored=0; +# unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { +# $sub_req->({command=>['runbeginpre'], +# node=>\@nodes, +# arg=>[$args[0]]},\&pass_along); +# } +# if ($errored) { return; } + #Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when #they specify no sharedtftp in site table my $stab = xCAT::Table->new('site'); - my $req = shift; my $sent = $stab->getAttribs({key=>'sharedtftp'},'value'); if ($sent and ($sent->{value} == 0 or $sent->{value} =~ /no/i)) { @@ -257,6 +325,7 @@ sub process_request { $request = shift; $callback = shift; $sub_req = shift; + my $command = $request->{command}->[0]; %breaknetbootnodes=(); %normalnodes=(); @@ -275,7 +344,6 @@ sub process_request { return; } - #back to normal business #if not shared tftpdir, then filter, otherwise, set up everything if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command @@ -288,28 +356,13 @@ sub process_request { } else { @nodes = @rnodes; } + #print "nodes=@nodes\nrnodes=@rnodes\n"; if (ref($request->{arg})) { @args=@{$request->{arg}}; } else { @args=($request->{arg}); } - - if(scalar grep /^--version$|^-v$/, @args) { - my $ver = xCAT::Utils->Version(); - my %rsp; - $rsp{data}->[0]="$ver"; - $callback->(\%rsp); - return; - } - if(scalar grep /^--help$|^-h$/, @args) { - if($usage{$request->{command}->[0]}) { - my %rsp; - $rsp{data}->[0]=$usage{$request->{command}->[0]}; - $callback->(\%rsp); - } - return; - } $errored=0; unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { @@ -318,6 +371,7 @@ sub process_request { arg=>[$args[0]]},\&pass_along); } if ($errored) { return; } + my $bptab=xCAT::Table->new('bootparams',-create=>1); my $bphash = $bptab->getNodesAttribs(\@nodes,['kernel','initrd','kcmdline','addkcmdline']); my $chaintab=xCAT::Table->new('chain',-create=>1); @@ -342,26 +396,34 @@ sub process_request { } } } - if ($request->{inittime}->[0]) { return; } #Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time - my @normalnodeset = keys %normalnodes; - if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command, only change local settings if already farmed - $sub_req->({command=>['makedhcp'],arg=>['-l'], - node=>\@normalnodeset},$callback); - } else { - $sub_req->({command=>['makedhcp'], - node=>\@normalnodeset},$callback); - } - my @breaknetboot=keys %breaknetbootnodes; - if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command - $sub_req->({command=>['makedhcp'], - node=>\@breaknetboot, - arg=>['-l','-s','filename = \"xcat/nonexistant_file_to_intentionally_break_netboot_for_localboot_to_work\";']},$callback); - } else { - $sub_req->({command=>['makedhcp'], - node=>\@breaknetboot, - arg=>['-s','filename = \"xcat/nonexistant_file_to_intentionally_break_netboot_for_localboot_to_work\";']},$callback); - } + my $inittime=0; + if (exists($request->{inittime})) { $inittime= $request->{inittime}->[0];} + if (!$inittime) { $inittime=0;} + my @normalnodeset = keys %normalnodes; + my @breaknetboot=keys %breaknetbootnodes; + #print "yaboot:inittime=$inittime; normalnodeset=@normalnodeset; breaknetboot=@breaknetboot\n"; + + #now run the end part of the prescripts + unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') + $errored=0; + if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children + $sub_req->({command=>['runendpre'], + node=>\@nodes, + inittime=>[$inittime], + normalnodeset=>\@normalnodeset, + breaknetboot=>\@breaknetboot, + 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 + $sub_req->({command=>['runendpre'], + node=>\@rnodes, + inittime=>[$inittime], + normalnodeset=>\@normalnodeset, + breaknetboot=>\@breaknetboot, + arg=>[$args[0]]},\&pass_along); + } + if ($errored) { return; } + } } #---------------------------------------------------------------------------- diff --git a/xCAT/prescripts/setupdhcp b/xCAT/prescripts/setupdhcp new file mode 100644 index 000000000..64cdbe344 --- /dev/null +++ b/xCAT/prescripts/setupdhcp @@ -0,0 +1,27 @@ +#!/bin/sh +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +#------------------------------------------------------------------------------- +#=head1 setupdhcp +#=head2 setupdhcp command is called by nodeset command as a end script. +# It configures the local dhcp lease file. +#=cut +#------------------------------------------------------------------------------- +#the following 3 variables are set in yahoo.pm and pxe.pm. +inittime=$1 + +if [[ $inittime -eq 1 ]]; then + exit 0 #Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time +fi + +normalnodeset=$2 +breaknetboot=$3 +if [ $normalnodeset != "NONE" ]; then + TMP=`XCATBYPASS=Y $XCATROOT/sbin/makedhcp $normalnodeset -l` + echo $TMP +fi +if [ $breaknetboot != "NONE" ]; then + TMP=`XCATBYPASS=Y $XCATROOT/sbin/makedhcp $breaknetboot -l -s 'filename = \"xcat/nonexistant_file_to_intentionally_break_netboot_for_localboot_to_work\";'` + echo $TMP +fi +exit 0; diff --git a/xCAT/xCAT.spec b/xCAT/xCAT.spec index bec6c09f2..997eec989 100644 --- a/xCAT/xCAT.spec +++ b/xCAT/xCAT.spec @@ -13,6 +13,7 @@ BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root Source1: xcat.conf Source2: postscripts.tar.gz Source3: templates.tar.gz +Source4: prescripts.tar.gz Provides: xCAT = %{version} Requires: xCAT-server xCAT-client perl-DBD-SQLite @@ -44,6 +45,7 @@ hardware management and software management. %prep %ifos linux tar zxf %{SOURCE2} +tar zxf %{SOURCE4} %else rm -rf postscripts cp %{SOURCE2} /opt/freeware/src/packages/BUILD @@ -57,6 +59,7 @@ tar -xf postscripts.tar mkdir -p $RPM_BUILD_ROOT/etc/apache2/conf.d mkdir -p $RPM_BUILD_ROOT/etc/httpd/conf.d mkdir -p $RPM_BUILD_ROOT/install/postscripts +mkdir -p $RPM_BUILD_ROOT/install/prescripts mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/ cd $RPM_BUILD_ROOT/%{prefix}/share/xcat/ @@ -74,6 +77,7 @@ cd $RPM_BUILD_ROOT/install %ifos linux tar zxf %{SOURCE2} +tar zxf %{SOURCE4} %else cp %{SOURCE2} $RPM_BUILD_ROOT/install gunzip -f postscripts.tar.gz @@ -109,4 +113,5 @@ fi /etc/httpd/conf.d/xcat.conf /etc/apache2/conf.d/xcat.conf /install/postscripts +/install/prescripts %defattr(-,root,root)