added boottarget table
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2739 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		
							
								
								
									
										183
									
								
								xCAT-server/lib/xcat/plugins/boottarget.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								xCAT-server/lib/xcat/plugins/boottarget.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html | ||||
| package xCAT_plugin::boottarget; | ||||
| BEGIN | ||||
| { | ||||
|   $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; | ||||
| } | ||||
| use lib "$::XCATROOT/lib/perl"; | ||||
| use Storable qw(dclone); | ||||
| use Sys::Syslog; | ||||
| use Thread qw(yield); | ||||
| use POSIX qw(WNOHANG nice); | ||||
| use xCAT::Table; | ||||
| use xCAT::Utils; | ||||
| use xCAT::MsgUtils; | ||||
| use xCAT::Yum; | ||||
| use xCAT::Template; | ||||
| #use xCAT::Postage; | ||||
| use Data::Dumper; | ||||
| use Getopt::Long; | ||||
| Getopt::Long::Configure("bundling"); | ||||
| Getopt::Long::Configure("pass_through"); | ||||
| use File::Path; | ||||
| use File::Copy; | ||||
|  | ||||
|  | ||||
|  | ||||
| sub handled_commands | ||||
| { | ||||
|     return { | ||||
|             mknetboot => "nodetype:os=(boottarget)|(target)|(bt)", | ||||
| 	    mkinstall => "nodetype:os=(boottarget)|(target)|(bt)" | ||||
|             }; | ||||
| } | ||||
|  | ||||
| sub preprocess_request | ||||
| { | ||||
|     my $req      = shift; | ||||
|     my $callback = shift; | ||||
|     if ($req->{command}->[0] eq 'copycd') | ||||
|     {    #don't farm out copycd | ||||
|         return [$req]; | ||||
|     } | ||||
|  | ||||
|     my $stab = xCAT::Table->new('site'); | ||||
|     my $sent; | ||||
|     ($sent) = $stab->getAttribs({key => 'sharedtftp'}, 'value'); | ||||
|     unless (    $sent | ||||
|             and defined($sent->{value}) | ||||
|             and ($sent->{value} =~ /no/i or $sent->{value} =~ /0/)) | ||||
|     { | ||||
|  | ||||
|         #unless requesting no sharedtftp, don't make hierarchical call | ||||
|         return [$req]; | ||||
|     } | ||||
|  | ||||
|     my %localnodehash; | ||||
|     my %dispatchhash; | ||||
|     my $nrtab = xCAT::Table->new('noderes'); | ||||
|     my $nrents = $nrtab->getNodesAttribs($req->{node},[qw(tftpserver servicenode)]); | ||||
|     foreach my $node (@{$req->{node}}) | ||||
|     { | ||||
|         my $nodeserver; | ||||
|         my $tent = $nrents->{$node}->[0]; #$nrtab->getNodeAttribs($node, ['tftpserver']); | ||||
|         if ($tent) { $nodeserver = $tent->{tftpserver} } | ||||
|         unless ($tent and $tent->{tftpserver}) | ||||
|         { | ||||
|             $tent = $nrents->{$node}->[0]; #$nrtab->getNodeAttribs($node, ['servicenode']); | ||||
|             if ($tent) { $nodeserver = $tent->{servicenode} } | ||||
|         } | ||||
|         if ($nodeserver) | ||||
|         { | ||||
|             $dispatchhash{$nodeserver}->{$node} = 1; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             $localnodehash{$node} = 1; | ||||
|         } | ||||
|     } | ||||
|     my @requests; | ||||
|     my $reqc = {%$req}; | ||||
|     $reqc->{node} = [keys %localnodehash]; | ||||
|     if (scalar(@{$reqc->{node}})) { push @requests, $reqc } | ||||
|  | ||||
|     foreach my $dtarg (keys %dispatchhash) | ||||
|     {    #iterate dispatch targets | ||||
|         my $reqcopy = {%$req};    #deep copy | ||||
|         $reqcopy->{'_xcatdest'} = $dtarg; | ||||
|         $reqcopy->{node} = [keys %{$dispatchhash{$dtarg}}]; | ||||
|         push @requests, $reqcopy; | ||||
|     } | ||||
|     return \@requests; | ||||
| } | ||||
|  | ||||
| sub process_request | ||||
| { | ||||
|     my $request  = shift; | ||||
|     my $callback = shift; | ||||
|     my $doreq    = shift; | ||||
|     my $distname = undef; | ||||
|     my $arch     = undef; | ||||
|     my $path     = undef; | ||||
|     return mknetboot($request, $callback, $doreq); | ||||
| } | ||||
|  | ||||
| sub mknetboot | ||||
| { | ||||
|     my $req      = shift; | ||||
|     my $callback = shift; | ||||
|     my $doreq    = shift; | ||||
|     my $tftpdir  = "/tftpboot"; | ||||
|     my $nodes    = @{$request->{node}}; | ||||
|     my @args     = @{$req->{arg}}; | ||||
|     my @nodes    = @{$req->{node}}; | ||||
|     my $ostab    = xCAT::Table->new('nodetype'); | ||||
|     my $sitetab  = xCAT::Table->new('site'); | ||||
|     my $installroot; | ||||
|     $installroot = "/install"; | ||||
|  | ||||
|     if ($sitetab) | ||||
|     { | ||||
|         (my $ref) = $sitetab->getAttribs({key => installdir}, value); | ||||
|         if ($ref and $ref->{value}) | ||||
|         { | ||||
|             $installroot = $ref->{value}; | ||||
|         } | ||||
|     } | ||||
|     my %donetftp=(); | ||||
|     my %oents = %{$ostab->getNodesAttribs(\@nodes,[qw(os arch profile)])}; | ||||
|     my $restab = xCAT::Table->new('noderes'); | ||||
|     my $bptab  = xCAT::Table->new('bootparams',-create=>1); | ||||
|     my $hmtab  = xCAT::Table->new('nodehm'); | ||||
|     my $ttab   = xCAT::Table->new('boottarget'); | ||||
|  | ||||
|     foreach $node (@nodes) | ||||
|     { | ||||
|         my $ent = $oents{$node}->[0]; #ostab->getNodeAttribs($node, ['os', 'arch', 'profile']); | ||||
|         unless ($ent->{os} and $ent->{profile}) | ||||
|         { | ||||
|             $callback->( | ||||
|                         { | ||||
|                          error     => ["Insufficient nodetype entry for $node"], | ||||
|                          errorcode => [1] | ||||
|                         } | ||||
|                         ); | ||||
|             next; | ||||
|         } | ||||
| 	 | ||||
|         my $profile = $ent->{profile}; | ||||
|     	($tent) = $ttab->getAttribs({'bprofile' => $profile}, 'kernel', 'initrd', 'kcmdline'); | ||||
| 	if(! defined($tent)){ | ||||
| 		my $msg =  "$profile in nodetype table was not defined in boottarget table"; | ||||
| 		$callback->({ | ||||
| 			error => ["$msg"], | ||||
| 	                errorcode => [1] | ||||
| 		}); | ||||
| 	} | ||||
| 	$kernel = $tent->{kernel}; | ||||
| 	$initrd = $tent->{initrd}; | ||||
| 	$kcmdline = $tent->{kcmdline}; | ||||
| 	if($initrd eq ''){ | ||||
|         	$bptab->setNodeAttribs( | ||||
|                       $node, | ||||
|                       { | ||||
|                        kernel => $kernel, | ||||
|                        initrd => '', | ||||
|                        kcmdline => $kcmdline | ||||
|                       } | ||||
|                      ); | ||||
| 	}else{ | ||||
|         	$bptab->setNodeAttribs( | ||||
|                       $node, | ||||
|                       { | ||||
|                        kernel => $kernel, | ||||
|                        initrd => $initrd, | ||||
|                        kcmdline => $kcmdline | ||||
|                       } | ||||
|                      ); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| 1; | ||||
		Reference in New Issue
	
	Block a user