From af98e241700e2705907b65e0a4c108c513736bf4 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Fri, 25 Sep 2009 20:30:05 +0000 Subject: [PATCH] -Roll pxe plugin all the way back to 2.2 style git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4233 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/lib/xcat/plugins/pxe.pm | 276 +++++++--------------------- 1 file changed, 69 insertions(+), 207 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/pxe.pm b/xCAT-server/lib/xcat/plugins/pxe.pm index 2ea8727d4..a6c259648 100644 --- a/xCAT-server/lib/xcat/plugins/pxe.pm +++ b/xCAT-server/lib/xcat/plugins/pxe.pm @@ -1,12 +1,10 @@ # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html package xCAT_plugin::pxe; +use Data::Dumper; use Sys::Syslog; use Socket; use File::Copy; -use File::Path; -use Getopt::Long; -my $addkcmdlinehandled; my $request; my $callback; my $dhcpconf = "/etc/dhcpd.conf"; @@ -14,7 +12,7 @@ my $tftpdir = "/tftpboot"; #my $dhcpver = 3; my %usage = ( - "nodeset" => "Usage: nodeset [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot|osimage=]", + "nodeset" => "Usage: nodeset [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot]", ); sub handled_commands { return { @@ -41,16 +39,7 @@ sub check_dhcp { sub getstate { my $node = shift; if (check_dhcp($node)) { - if (-r $tftpdir . "/xcat/xnba/nodes/".$node) { - my $fhand; - open ($fhand,$tftpdir . "/xcat/xnba/nodes/".$node); - my $headline = <$fhand>; - $headline = <$fhand>; #second line is the comment now... - close $fhand; - $headline =~ s/^#//; - chomp($headline); - return $headline; - } elsif (-r $tftpdir . "/pxelinux.cfg/".$node) { + if (-r $tftpdir . "/pxelinux.cfg/".$node) { my $fhand; open ($fhand,$tftpdir . "/pxelinux.cfg/".$node); my $headline = <$fhand>; @@ -77,14 +66,8 @@ sub setstate { my %chainhash = %{shift()}; my %machash = %{shift()}; my $kern = $bphash{$node}->[0]; #$bptab->getNodeAttribs($node,['kernel','initrd','kcmdline']); - unless ($addkcmdlinehandled->{$node}) { #Tag to let us know the plugin had a special syntax implemented for addkcmdline - if ($kern->{addkcmdline}) { #Implement the kcmdline append here for - #most generic, least code duplication - $kern->{kcmdline} .= " ".$kern->{addkcmdline}; - } - } if ($kern->{kcmdline} =~ /!myipfn!/) { - my $ipfn = '${next-server}';#xCAT::Utils->my_ip_facing($node); + my $ipfn = xCAT::Utils->my_ip_facing($node); unless ($ipfn) { my @myself = xCAT::Utils->determinehostname(); my $myname = $myself[(scalar @myself)-1]; @@ -97,67 +80,40 @@ sub setstate { } ); } - $kern->{kcmdline} =~ s/!myipfn!/$ipfn/g; + $kern->{kcmdline} =~ s/!myipfn!/$ipfn/; } my $pcfg; - unlink($tftpdir."/xcat/xnba/nodes/".$node.".pxelinux"); - open($pcfg,'>',$tftpdir."/xcat/xnba/nodes/".$node); + open($pcfg,'>',$tftpdir."/pxelinux.cfg/".$node); my $cref=$chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']); - print $pcfg "#!gpxe\n"; if ($cref->{currstate}) { print $pcfg "#".$cref->{currstate}."\n"; } + print $pcfg "DEFAULT xCAT\n"; + print $pcfg "LABEL xCAT\n"; if ($cref and $cref->{currstate} eq "boot") { - print $pcfg "exit\n"; + print $pcfg "LOCALBOOT 0\n"; close($pcfg); } elsif ($kern and $kern->{kernel}) { - if ($kern->{kernel} =~ /!/) { #TODO: deprecate this, do stateless Xen like stateless ESXi - my $hypervisor; - my $kernel; - ($kernel,$hypervisor) = split /!/,$kern->{kernel}; - print $pcfg " set 209:string xcat/xnba/nodes/$node.pxelinux\n"; - print $pcfg " set 210:string http://".'${next-server}'."/tftpboot/\n"; - print $pcfg " imgfetch -n pxelinux.0 http://".'${next-server}'."/tftpboot/xcat/pxelinux.0\n"; - print $pcfg " imgload pxelinux.0\n"; - print $pcfg " imgexec pxelinux.0\n"; - close($pcfg); - open($pcfg,'>',$tftpdir."/xcat/xnba/nodes/".$node.".pxelinux"); - print $pcfg "DEFAULT xCAT\nLABEL xCAT\n KERNEL mboot.c32\n"; - print $pcfg " APPEND $hypervisor --- $kernel ".$kern->{kcmdline}." --- ".$kern->{initrd}."\n"; + if ($kern->{kernel} =~ /!/) { + my $hypervisor; + my $kernel; + ($kernel,$hypervisor) = split /!/,$kern->{kernel}; + print $pcfg " KERNEL mboot.c32\n"; + print $pcfg " APPEND $hypervisor --- $kernel ".$kern->{kcmdline}." --- ".$kern->{initrd}."\n"; } else { - if ($kern->{kernel} =~ /\.c32\z/ or $kern->{kernel} =~ /memdisk\z/) { #gPXE comboot support seems insufficient, chain pxelinux instead - print $pcfg " set 209:string xcat/xnba/nodes/$node.pxelinux\n"; - print $pcfg " set 210:string http://".'${next-server}'."/tftpboot/\n"; - print $pcfg " imgfetch -n pxelinux.0 http://".'${next-server}'."/tftpboot/xcat/pxelinux.0\n"; - print $pcfg " imgload pxelinux.0\n"; - print $pcfg " imgexec pxelinux.0\n"; - close($pcfg); - open($pcfg,'>',$tftpdir."/xcat/xnba/nodes/".$node.".pxelinux"); - #It's time to set pxelinux for this node to boot the kernel.. - print $pcfg "DEFAULT xCAT\nLABEL xCAT\n"; - print $pcfg " KERNEL ".$kern->{kernel}."\n"; - if ($kern->{initrd} or $kern->{kcmdline}) { - print $pcfg " APPEND "; - } - if ($kern and $kern->{initrd}) { - print $pcfg "initrd=".$kern->{initrd}." "; - } - if ($kern and $kern->{kcmdline}) { - print $pcfg $kern->{kcmdline}."\n"; - } else { - print $pcfg "\n"; - } - } else { #other than comboot/multiboot, we won't have need of pxelinux - print $pcfg "imgfetch -n kernel http://".'${next-server}/tftpboot/'.$kern->{kernel}."\n"; - print $pcfg "imgload kernel\n"; - if ($kern->{kcmdline}) { - print $pcfg "imgargs kernel ".$kern->{kcmdline}."\n"; - } - if ($kern->{initrd}) { - print $pcfg "imgfetch http://".'${next-server}'."/tftpboot/".$kern->{initrd}."\n"; - } - print $pcfg "imgexec kernel\n"; - } + #It's time to set pxelinux for this node to boot the kernel.. + print $pcfg " KERNEL ".$kern->{kernel}."\n"; + if ($kern->{initrd} or $kern->{kcmdline}) { + print $pcfg " APPEND "; + } + if ($kern and $kern->{initrd}) { + print $pcfg "initrd=".$kern->{initrd}." "; + } + if ($kern and $kern->{kcmdline}) { + print $pcfg $kern->{kcmdline}."\n"; + } else { + print $pcfg "\n"; + } } close($pcfg); my $inetn = inet_aton($node); @@ -212,6 +168,7 @@ sub setstate { my $errored = 0; sub pass_along { my $resp = shift; + $callback->($resp); if ($resp and ($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) { $errored=1; } @@ -219,72 +176,16 @@ sub pass_along { if ($_->{error} or $_->{errorcode}) { $errored=1; } - if ($_->{_addkcmdlinehandled}) { - $addkcmdlinehandled->{$_->{name}->[0]}=1; - return; #Don't send back to client this internal hint - } } - $callback->($resp); } + sub preprocess_request { - my $req = shift; - if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; } - - my $callback1 = 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}; - $callback1->(\%rsp); - } - return; - } - - if ($HELP) { - if($usage{$command}) { - my %rsp; - $rsp{data}->[0]=$usage{$command}; - $callback1->(\%rsp); - } - return; - } - - if ($VERSION) { - my $ver = xCAT::Utils->Version(); - my %rsp; - $rsp{data}->[0]="$ver"; - $callback1->(\%rsp); - return; - } - - if (@ARGV==0) { - if($usage{$command}) { - my %rsp; - $rsp{data}->[0]=$usage{$command}; - $callback1->(\%rsp); - } - 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]; @@ -298,7 +199,7 @@ sub preprocess_request { #sub preprocess_request { # my $req = shift; # $callback = shift; -# if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; } +# if ($req->{_xcatdest}) { return [$req]; } #Exit if the packet has been preprocessed in its history # my @requests = ({%$req}); #Start with a straight copy to reflect local instance # my $sitetab = xCAT::Table->new('site'); # (my $ent) = $sitetab->getAttribs({key=>'xcatservers'},'value'); @@ -308,7 +209,6 @@ sub preprocess_request { # if (xCAT::Utils->thishostisnot($_)) { # my $reqcopy = {%$req}; # $reqcopy->{'_xcatdest'} = $_; -# $reqcopy->{_xcatpreprocessed}->[0] = 1; # push @requests,$reqcopy; # } # } @@ -362,6 +262,15 @@ 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]}}); @@ -380,63 +289,44 @@ sub process_request { } else { @nodes = @rnodes; } - - if (ref($request->{arg})) { - @args=@{$request->{arg}}; - } else { - @args=($request->{arg}); - } - - #now run the begin 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=>['runbeginpre'], - node=>\@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=>['runbeginpre'], - node=>\@rnodes, - arg=>[$args[0]]},\&pass_along); - } - if ($errored) { return; } - } - - #back to normal business - if (! -r "$tftpdir/xcat/pxelinux.0") { - unless (-r $::XCATROOT."/share/xcat/netboot/syslinux/pxelinux.0") { - $callback->({error=>["Unable to find pxelinux.0 at ".$::XCATROOT."/share/xcat/netboot/syslinux/pxelinux.0"],errorcode=>[1]}); + + if (! -r "$tftpdir/pxelinux.0") { + unless (-r "/usr/lib/syslinux/pxelinux.0" or -r "/usr/share/syslinux/pxelinux.0") { + $callback->({error=>["Unable to find pxelinux.0 "],errorcode=>[1]}); return; } - copy($::XCATROOT."/share/xcat/netboot/syslinux/pxelinux.0","$tftpdir/xcat/pxelinux.0"); + if (-r "/usr/lib/syslinux/pxelinux.0") { + copy("/usr/lib/syslinux/pxelinux.0","$tftpdir/pxelinux.0"); + } else { + copy("/usr/share/syslinux/pxelinux.0","$tftpdir/pxelinux.0"); + } chmod(0644,"$tftpdir/pxelinux.0"); } - unless ( -r "$tftpdir/xcat/pxelinux.0" ) { + unless ( -r "$tftpdir/pxelinux.0" ) { $callback->({errror=>["Unable to find pxelinux.0 from syslinux"],errorcode=>[1]}); return; } - - my $inittime=0; - if (exists($request->{inittime})) { $inittime= $request->{inittime}->[0];} - if (!$inittime) { $inittime=0;} + if (ref($request->{arg})) { + @args=@{$request->{arg}}; + } else { + @args=($request->{arg}); + } $errored=0; unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { - $sub_req->({command=>['setdestiny'], - node=>\@nodes, - inittime=>[$inittime], - arg=>[$args[0]]},\&pass_along); + $sub_req->({command=>['setdestiny'], + node=>\@nodes, + arg=>[$args[0]]},\&pass_along); } if ($errored) { return; } #Time to actually configure the nodes, first extract database data with the scalable calls my $bptab = xCAT::Table->new('bootparams',-create=>1); my $chaintab = xCAT::Table->new('chain'); my $mactab = xCAT::Table->new('mac'); #to get all the hostnames - my %bphash = %{$bptab->getNodesAttribs(\@nodes,[qw(kernel initrd kcmdline addkcmdline)])}; + my %bphash = %{$bptab->getNodesAttribs(\@nodes,[qw(kernel initrd kcmdline)])}; my %chainhash = %{$chaintab->getNodesAttribs(\@nodes,[qw(currstate)])}; my %machash = %{$mactab->getNodesAttribs(\@nodes,[qw(mac)])}; - mkpath($tftpdir."/xcat/xnba/nodes/"); foreach (@nodes) { my %response; $response{node}->[0]->{name}->[0]=$_; @@ -452,43 +342,15 @@ sub process_request { } } } - - - #dhcp stuff -- inittime is set when xcatd on sn is started - unless (($args[0] eq 'stat') || ($inittime)) { - my $do_dhcpsetup=1; - my $sitetab = xCAT::Table->new('site'); - if ($sitetab) { - (my $ref) = $sitetab->getAttribs({key => 'dhcpsetup'}, 'value'); - if ($ref) { - if ($ref->{value} =~ /0|n|N/) { $do_dhcpsetup=0; } - } - } - - if ($do_dhcpsetup) { - 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); - } - } - } - - #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, - 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, - arg=>[$args[0]]},\&pass_along); - } - if ($errored) { return; } + 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); + } } }