| 
							
							
							
						 |  |  | @@ -1,5 +1,11 @@ | 
		
	
		
			
				|  |  |  |  | # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html | 
		
	
		
			
				|  |  |  |  | package xCAT_plugin::destiny; | 
		
	
		
			
				|  |  |  |  | BEGIN | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | use lib "$::XCATROOT/lib/perl"; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | use xCAT::NodeRange; | 
		
	
		
			
				|  |  |  |  | use Data::Dumper; | 
		
	
		
			
				|  |  |  |  | use xCAT::Utils; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -77,305 +83,377 @@ sub relay_response { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | sub setdestiny { | 
		
	
		
			
				|  |  |  |  |   my $req=shift; | 
		
	
		
			
				|  |  |  |  |   my $flag=shift; | 
		
	
		
			
				|  |  |  |  |   my $noupdate=shift; | 
		
	
		
			
				|  |  |  |  |     my $req=shift; | 
		
	
		
			
				|  |  |  |  |     my $flag=shift; | 
		
	
		
			
				|  |  |  |  |     my $noupdate=shift; | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     $chaintab = xCAT::Table->new('chain',-create=>1); | 
		
	
		
			
				|  |  |  |  |     my @nodes=@{$req->{node}}; | 
		
	
		
			
				|  |  |  |  |     my $state = $req->{arg}->[0]; | 
		
	
		
			
				|  |  |  |  |     my %nstates; | 
		
	
		
			
				|  |  |  |  |     if ($state eq "enact") { | 
		
	
		
			
				|  |  |  |  | 	my $nodetypetab = xCAT::Table->new('nodetype',-create=>1); | 
		
	
		
			
				|  |  |  |  | 	my %nodestates; | 
		
	
		
			
				|  |  |  |  | 	my %stents = %{$chaintab->getNodesAttribs($req->{node},"currstate")}; | 
		
	
		
			
				|  |  |  |  | 	my %ntents = %{$nodetypetab->getNodesAttribs($req->{node},"provmethod")}; | 
		
	
		
			
				|  |  |  |  | 	my $state; | 
		
	
		
			
				|  |  |  |  | 	my $sninit=0; | 
		
	
		
			
				|  |  |  |  | 	if (exists($req->{inittime})) { # this is called in AAsn.pm | 
		
	
		
			
				|  |  |  |  | 	    $sninit=$req->{inittime}->[0]; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	foreach (@{$req->{node}}) { #First, build a hash of all of the states to attempt to keep things as aggregated as possible | 
		
	
		
			
				|  |  |  |  | 	    if ($stents{$_}->[0]->{currstate}) { | 
		
	
		
			
				|  |  |  |  | 		$state = $stents{$_}->[0]->{currstate}; | 
		
	
		
			
				|  |  |  |  | 		$state =~ s/ .*//; | 
		
	
		
			
				|  |  |  |  | 		#get the osimagename if nodetype.provmethod has osimage specified | 
		
	
		
			
				|  |  |  |  | 		if (($sninit ==1) && (($state eq 'install') || ($state eq 'netboot') || ($state eq 'statelite'))) { | 
		
	
		
			
				|  |  |  |  | 		    my $osimage=$ntents{$_}->[0]->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 		    if (($osimage) && ($osimage ne 'install') && ($osimage ne 'netboot') && ($osimage ne 'statelite')) { | 
		
	
		
			
				|  |  |  |  | 			$state="osimage=$osimage";  | 
		
	
		
			
				|  |  |  |  | 		    } | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		push @{$nodestates{$state}},$_; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	foreach (keys %nodestates) { | 
		
	
		
			
				|  |  |  |  | 	    $req->{arg}->[0]=$_; | 
		
	
		
			
				|  |  |  |  | 	    $req->{node} = $nodestates{$_}; | 
		
	
		
			
				|  |  |  |  | 	    setdestiny($req,30,1); #ludicrous flag to denote no table updates can be inferred. | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	return; | 
		
	
		
			
				|  |  |  |  |     } elsif ($state eq "next") { | 
		
	
		
			
				|  |  |  |  | 	return nextdestiny($flag + 1);  #this is special case where updateflag is called | 
		
	
		
			
				|  |  |  |  |     } 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]}); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	my $bptab = xCAT::Table->new('bootparams',-create=>1); | 
		
	
		
			
				|  |  |  |  | 	my $nodetype = xCAT::Table->new('nodetype'); | 
		
	
		
			
				|  |  |  |  | 	my $ntents = $nodetype->getNodesAttribs($req->{node},[qw(os arch profile)]); | 
		
	
		
			
				|  |  |  |  | 	my $ients = $iscsitab->getNodesAttribs($req->{node},[qw(kernel kcmdline initrd)]); | 
		
	
		
			
				|  |  |  |  | 	foreach (@{$req->{node}}) { | 
		
	
		
			
				|  |  |  |  | 	    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 | 
		
	
		
			
				|  |  |  |  | 		next; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	    my $hash; | 
		
	
		
			
				|  |  |  |  | 	    $hash->{kernel} = $ient->{kernel}; | 
		
	
		
			
				|  |  |  |  | 	    if ($ient->{initrd}) { $hash->{initrd} = $ient->{initrd} } | 
		
	
		
			
				|  |  |  |  | 	    if ($ient->{kcmdline}) { $hash->{kcmdline} = $ient->{kcmdline} } | 
		
	
		
			
				|  |  |  |  | 	    $bptab->setNodeAttribs($_,$hash); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |     } 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; | 
		
	
		
			
				|  |  |  |  | 	if ($state =~ /=/) { | 
		
	
		
			
				|  |  |  |  | 	    ($state,$target) = split '=',$state,2; | 
		
	
		
			
				|  |  |  |  | 	    if ($target =~ /:/) { | 
		
	
		
			
				|  |  |  |  | 		($target, $action) = split ':',$target,2; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	} else { | 
		
	
		
			
				|  |  |  |  | 	    if ($state =~ /:/) { | 
		
	
		
			
				|  |  |  |  | 		($state, $action) = split ':',$state,2; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   $chaintab = xCAT::Table->new('chain',-create=>1); | 
		
	
		
			
				|  |  |  |  |   my @nodes=@{$req->{node}}; | 
		
	
		
			
				|  |  |  |  |   my $state = $req->{arg}->[0]; | 
		
	
		
			
				|  |  |  |  |   my %nstates; | 
		
	
		
			
				|  |  |  |  |   if ($state eq "enact") { | 
		
	
		
			
				|  |  |  |  |       my $nodetypetab = xCAT::Table->new('nodetype',-create=>1); | 
		
	
		
			
				|  |  |  |  |       my %nodestates; | 
		
	
		
			
				|  |  |  |  |       my %stents = %{$chaintab->getNodesAttribs($req->{node},"currstate")}; | 
		
	
		
			
				|  |  |  |  |       my %ntents = %{$nodetypetab->getNodesAttribs($req->{node},"provmethod")}; | 
		
	
		
			
				|  |  |  |  |       my $state; | 
		
	
		
			
				|  |  |  |  |       my $sninit=0; | 
		
	
		
			
				|  |  |  |  |       if (exists($req->{inittime})) { # this is called in AAsn.pm | 
		
	
		
			
				|  |  |  |  | 	  $sninit=$req->{inittime}->[0]; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |         foreach my $tmpnode (@{$req->{node}}) { | 
		
	
		
			
				|  |  |  |  | 	    $state_hash{$tmpnode}=$state; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       foreach (@{$req->{node}}) { #First, build a hash of all of the states to attempt to keep things as aggregated as possible | 
		
	
		
			
				|  |  |  |  |           if ($stents{$_}->[0]->{currstate}) { | 
		
	
		
			
				|  |  |  |  |               $state = $stents{$_}->[0]->{currstate}; | 
		
	
		
			
				|  |  |  |  |               $state =~ s/ .*//; | 
		
	
		
			
				|  |  |  |  |               #get the osimagename if nodetype.provmethod has osimage specified | 
		
	
		
			
				|  |  |  |  | 	      if (($sninit ==1) && (($state eq 'install') || ($state eq 'netboot') || ($state eq 'statelite'))) { | 
		
	
		
			
				|  |  |  |  | 		  my $osimage=$ntents{$_}->[0]->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 		  if (($osimage) && ($osimage ne 'install') && ($osimage ne 'netboot') && ($osimage ne 'statelite')) { | 
		
	
		
			
				|  |  |  |  | 		     $state="osimage=$osimage";  | 
		
	
		
			
				|  |  |  |  | 		  } | 
		
	
		
			
				|  |  |  |  | 	      } | 
		
	
		
			
				|  |  |  |  |               push @{$nodestates{$state}},$_; | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       foreach (keys %nodestates) { | 
		
	
		
			
				|  |  |  |  |           $req->{arg}->[0]=$_; | 
		
	
		
			
				|  |  |  |  |           $req->{node} = $nodestates{$_}; | 
		
	
		
			
				|  |  |  |  |           setdestiny($req,30,1); #ludicrous flag to denote no table updates can be inferred. | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |   } elsif ($state eq "next") { | 
		
	
		
			
				|  |  |  |  |     return nextdestiny($flag + 1);  #this is special case where updateflag is called | 
		
	
		
			
				|  |  |  |  |   } 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]}); | 
		
	
		
			
				|  |  |  |  |      } | 
		
	
		
			
				|  |  |  |  |      my $bptab = xCAT::Table->new('bootparams',-create=>1); | 
		
	
		
			
				|  |  |  |  |      my $nodetype = xCAT::Table->new('nodetype'); | 
		
	
		
			
				|  |  |  |  |      my $ntents = $nodetype->getNodesAttribs($req->{node},[qw(os arch profile)]); | 
		
	
		
			
				|  |  |  |  |      my $ients = $iscsitab->getNodesAttribs($req->{node},[qw(kernel kcmdline initrd)]); | 
		
	
		
			
				|  |  |  |  |      foreach (@{$req->{node}}) { | 
		
	
		
			
				|  |  |  |  |       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 | 
		
	
		
			
				|  |  |  |  |          next; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       my $hash; | 
		
	
		
			
				|  |  |  |  |       $hash->{kernel} = $ient->{kernel}; | 
		
	
		
			
				|  |  |  |  |       if ($ient->{initrd}) { $hash->{initrd} = $ient->{initrd} } | 
		
	
		
			
				|  |  |  |  |       if ($ient->{kcmdline}) { $hash->{kcmdline} = $ient->{kcmdline} } | 
		
	
		
			
				|  |  |  |  |       $bptab->setNodeAttribs($_,$hash); | 
		
	
		
			
				|  |  |  |  |      } | 
		
	
		
			
				|  |  |  |  |   } 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/) { | 
		
	
		
			
				|  |  |  |  |     chomp($state); | 
		
	
		
			
				|  |  |  |  |     my $target; | 
		
	
		
			
				|  |  |  |  |     my $action; | 
		
	
		
			
				|  |  |  |  |     if ($state =~ /=/) { | 
		
	
		
			
				|  |  |  |  |         ($state,$target) = split /=/,$state,2; | 
		
	
		
			
				|  |  |  |  |          if ($target =~ /:/) { | 
		
	
		
			
				|  |  |  |  |              ($target, $action) = split /:/,$target,2; | 
		
	
		
			
				|  |  |  |  |          } | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         if ($state =~ /:/) { | 
		
	
		
			
				|  |  |  |  |              ($state, $action) = split /:/,$state,2; | 
		
	
		
			
				|  |  |  |  |          } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     my $nodetypetable = xCAT::Table->new('nodetype', -create=>1); | 
		
	
		
			
				|  |  |  |  |     if ($state ne 'osimage') { | 
		
	
		
			
				|  |  |  |  |         my $updateattribs; | 
		
	
		
			
				|  |  |  |  |         if ($target) { | 
		
	
		
			
				|  |  |  |  |             my $archentries = $nodetypetable->getNodesAttribs($req->{node},['supportedarchs']); | 
		
	
		
			
				|  |  |  |  |             if ($target =~ /^([^-]*)-([^-]*)-(.*)/) { | 
		
	
		
			
				|  |  |  |  |                 $updateattribs->{os}=$1; | 
		
	
		
			
				|  |  |  |  |                 $updateattribs->{arch}=$2; | 
		
	
		
			
				|  |  |  |  |                 $updateattribs->{profile}=$3; | 
		
	
		
			
				|  |  |  |  |                 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; | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 } #end foreach | 
		
	
		
			
				|  |  |  |  |             } else { | 
		
	
		
			
				|  |  |  |  |                 $updateattribs->{profile}=$target; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } #end if($target)  | 
		
	
		
			
				|  |  |  |  |         $updateattribs->{provmethod}=$state; | 
		
	
		
			
				|  |  |  |  |         my @tmpnodelist = @{$req->{node}}; | 
		
	
		
			
				|  |  |  |  |         $nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  | 	if (@{$req->{node}} == 0) { return;} | 
		
	
		
			
				|  |  |  |  |         if ($target) { | 
		
	
		
			
				|  |  |  |  | 	    my $osimagetable=xCAT::Table->new('osimage'); | 
		
	
		
			
				|  |  |  |  |             (my $ref) = $osimagetable->getAttribs({imagename => $target}, 'provmethod', 'osvers', 'profile', 'osarch'); | 
		
	
		
			
				|  |  |  |  |             if ($ref) { | 
		
	
		
			
				|  |  |  |  | 		if ($ref->{provmethod}) { | 
		
	
		
			
				|  |  |  |  | 		    $state=$ref->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 	my $nodetypetable = xCAT::Table->new('nodetype', -create=>1); | 
		
	
		
			
				|  |  |  |  | 	if ($state ne 'osimage') { | 
		
	
		
			
				|  |  |  |  | 	    my $updateattribs; | 
		
	
		
			
				|  |  |  |  | 	    if ($target) { | 
		
	
		
			
				|  |  |  |  | 		my $archentries = $nodetypetable->getNodesAttribs($req->{node},['supportedarchs']); | 
		
	
		
			
				|  |  |  |  | 		if ($target =~ /^([^-]*)-([^-]*)-(.*)/) { | 
		
	
		
			
				|  |  |  |  | 		    $updateattribs->{os}=$1; | 
		
	
		
			
				|  |  |  |  | 		    $updateattribs->{arch}=$2; | 
		
	
		
			
				|  |  |  |  | 		    $updateattribs->{profile}=$3; | 
		
	
		
			
				|  |  |  |  | 		    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; | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 		    } #end foreach | 
		
	
		
			
				|  |  |  |  | 		} else { | 
		
	
		
			
				|  |  |  |  | 		    $errored =1; $callback->({error=>"osimage.provmethod for $target must be set."}); | 
		
	
		
			
				|  |  |  |  | 		    $updateattribs->{profile}=$target; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	    } #end if($target)  | 
		
	
		
			
				|  |  |  |  | 	    $updateattribs->{provmethod}=$state; | 
		
	
		
			
				|  |  |  |  | 	    my @tmpnodelist = @{$req->{node}}; | 
		
	
		
			
				|  |  |  |  | 	    $nodetypetable->setNodesAttribs(\@tmpnodelist, $updateattribs); | 
		
	
		
			
				|  |  |  |  | 	} else { #state is osimage | 
		
	
		
			
				|  |  |  |  | 	    if (@{$req->{node}} == 0) { return;} | 
		
	
		
			
				|  |  |  |  | 	    if ($target) { | 
		
	
		
			
				|  |  |  |  | 		my $osimagetable=xCAT::Table->new('osimage'); | 
		
	
		
			
				|  |  |  |  | 		(my $ref) = $osimagetable->getAttribs({imagename => $target}, 'provmethod', 'osvers', 'profile', 'osarch'); | 
		
	
		
			
				|  |  |  |  | 		if ($ref) { | 
		
	
		
			
				|  |  |  |  | 		    if ($ref->{provmethod}) { | 
		
	
		
			
				|  |  |  |  | 			$state=$ref->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 		    } else { | 
		
	
		
			
				|  |  |  |  | 			$errored =1; $callback->({error=>"osimage.provmethod for $target must be set."}); | 
		
	
		
			
				|  |  |  |  | 			return; | 
		
	
		
			
				|  |  |  |  | 		    } | 
		
	
		
			
				|  |  |  |  | 		} else { | 
		
	
		
			
				|  |  |  |  | 		    $errored =1; $callback->({error=>"Cannot find the OS image $target on the osimage table."}); | 
		
	
		
			
				|  |  |  |  | 		    return; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	    } else { | 
		
	
		
			
				|  |  |  |  | 		$errored =1; $callback->({error=>"Cannot find the OS image $target on the osimage table."}); | 
		
	
		
			
				|  |  |  |  | 		my $updateattribs; | 
		
	
		
			
				|  |  |  |  | 		$updateattribs->{provmethod}=$target; | 
		
	
		
			
				|  |  |  |  | 		$updateattribs->{profile}=$ref->{profile}; | 
		
	
		
			
				|  |  |  |  | 		$updateattribs->{os}=$ref->{osvers}; | 
		
	
		
			
				|  |  |  |  | 		$updateattribs->{arch}=$ref->{osarch}; | 
		
	
		
			
				|  |  |  |  | 		my @tmpnodelist = @{$req->{node}}; | 
		
	
		
			
				|  |  |  |  | 		$nodetypetable->setNodesAttribs(\@tmpnodelist,$updateattribs); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		foreach my $tmpnode (@{$req->{node}}) { | 
		
	
		
			
				|  |  |  |  | 		    $state_hash{$tmpnode}=$state; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 	    } else {  | 
		
	
		
			
				|  |  |  |  | 		my @errornodes=(); | 
		
	
		
			
				|  |  |  |  | 		my $updatestuff; | 
		
	
		
			
				|  |  |  |  | 		my $nodetypetable = xCAT::Table->new('nodetype', -create=>1); | 
		
	
		
			
				|  |  |  |  | 		my %ntents = %{$nodetypetable->getNodesAttribs($req->{node},"provmethod")}; | 
		
	
		
			
				|  |  |  |  | 		foreach my $tmpnode (@{$req->{node}}) {  | 
		
	
		
			
				|  |  |  |  | 		    my $osimage=$ntents{$tmpnode}->[0]->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 		    if (($osimage) && ($osimage ne 'install') && ($osimage ne 'netboot') && ($osimage ne 'statelite')) { | 
		
	
		
			
				|  |  |  |  | 			if (!exists($updatestuff->{$osimage})) { | 
		
	
		
			
				|  |  |  |  | 			    my $osimagetable=xCAT::Table->new('osimage'); | 
		
	
		
			
				|  |  |  |  | 			    (my $ref) = $osimagetable->getAttribs({imagename => $osimage}, 'provmethod', 'osvers', 'profile', 'osarch'); | 
		
	
		
			
				|  |  |  |  | 			    if ($ref) { | 
		
	
		
			
				|  |  |  |  | 				if ($ref->{provmethod}) { | 
		
	
		
			
				|  |  |  |  | 				    $state=$ref->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 				    $state_hash{$tmpnode}=$state; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 				    $updatestuff->{$osimage}->{state}=$state; | 
		
	
		
			
				|  |  |  |  | 				    $updatestuff->{$osimage}->{nodes}=[$tmpnode]; | 
		
	
		
			
				|  |  |  |  | 				    $updatestuff->{$osimage}->{profile}=$ref->{profile}; | 
		
	
		
			
				|  |  |  |  | 				    $updatestuff->{$osimage}->{os}=$ref->{osvers}; | 
		
	
		
			
				|  |  |  |  | 				    $updatestuff->{$osimage}->{arch}=$ref->{osarch}; | 
		
	
		
			
				|  |  |  |  | 				} else { | 
		
	
		
			
				|  |  |  |  | 				    $errored =1; $callback->({error=>"osimage.provmethod for $osimage must be set."}); | 
		
	
		
			
				|  |  |  |  | 				    return; | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 			    } else { | 
		
	
		
			
				|  |  |  |  | 				$errored =1; $callback->({error=>"Cannot find the OS image $osimage on the osimage table."}); | 
		
	
		
			
				|  |  |  |  | 				return; | 
		
	
		
			
				|  |  |  |  | 			    } | 
		
	
		
			
				|  |  |  |  | 			} else { | 
		
	
		
			
				|  |  |  |  | 			    my $nodes= $updatestuff->{$osimage}->{nodes}; | 
		
	
		
			
				|  |  |  |  | 			    push (@$nodes, $tmpnode); | 
		
	
		
			
				|  |  |  |  | 			    $state_hash{$tmpnode}=$updatestuff->{$osimage}->{state}; | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			 | 
		
	
		
			
				|  |  |  |  | 		    } else { | 
		
	
		
			
				|  |  |  |  | 			push(@errornodes, $tmpnode); | 
		
	
		
			
				|  |  |  |  | 		    } | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 		if (@errornodes) { | 
		
	
		
			
				|  |  |  |  | 		    $errored =1; $callback->({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); | 
		
	
		
			
				|  |  |  |  | 		    }  | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	#print Dumper($req); | 
		
	
		
			
				|  |  |  |  | 	# if precreatemypostscripts=1, create each mypostscript for each node | 
		
	
		
			
				|  |  |  |  | 	# otherwise, create it during installation /updatenode | 
		
	
		
			
				|  |  |  |  | 	require xCAT::Postage; | 
		
	
		
			
				|  |  |  |  | 	xCAT::Postage::create_mypostscript_or_not($request, $callback, $subreq);  | 
		
	
		
			
				|  |  |  |  |         | 
		
	
		
			
				|  |  |  |  |         my %state_hash1;  | 
		
	
		
			
				|  |  |  |  | 	foreach my $tmpnode (keys(%state_hash)) { | 
		
	
		
			
				|  |  |  |  | 	    push @{$state_hash1{$state_hash{$tmpnode}}},$tmpnode; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	#print Dumper(%state_hash); | 
		
	
		
			
				|  |  |  |  | 	#print Dumper(%state_hash1); | 
		
	
		
			
				|  |  |  |  | 	foreach my $tempstate (keys %state_hash1) { | 
		
	
		
			
				|  |  |  |  | 	    my $samestatenodes=$state_hash1{$tempstate}; | 
		
	
		
			
				|  |  |  |  | 	    #print "state=$tempstate nodes=@$samestatenodes\n";	 | 
		
	
		
			
				|  |  |  |  | 	    $errored=0; | 
		
	
		
			
				|  |  |  |  | 	    $subreq->({command=>["mk$tempstate"], | 
		
	
		
			
				|  |  |  |  | 		       node=>$samestatenodes}, \&relay_response); | 
		
	
		
			
				|  |  |  |  | 	    if ($errored) {  | 
		
	
		
			
				|  |  |  |  | 		$callback->({error=>"Some nodes failed to set up $state resources, aborting"}); | 
		
	
		
			
				|  |  |  |  | 		return;  | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	    my $ntents = $nodetypetable->getNodesAttribs($samestatenodes,[qw(os arch profile)]); | 
		
	
		
			
				|  |  |  |  | 	    foreach (@{$samestatenodes}) { | 
		
	
		
			
				|  |  |  |  | 		$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->({error=>"nodetype.os not defined for $_"}); } | 
		
	
		
			
				|  |  |  |  | 		} else { | 
		
	
		
			
				|  |  |  |  | 		    $nstates{$_} .= " winpe"; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		if ($ntent and $ntent->{arch}) { | 
		
	
		
			
				|  |  |  |  | 		    $nstates{$_} .= "-".$ntent->{arch}; | 
		
	
		
			
				|  |  |  |  | 		} else { $errored =1; $callback->({error=>"nodetype.arch not defined for $_"}); } | 
		
	
		
			
				|  |  |  |  | 		if ($tempstate ne "winshell") { | 
		
	
		
			
				|  |  |  |  | 		    if ($ntent and $ntent->{profile}) { | 
		
	
		
			
				|  |  |  |  | 			$nstates{$_} .= "-".$ntent->{profile}; | 
		
	
		
			
				|  |  |  |  | 		    } else { $errored =1; $callback->({error=>"nodetype.profile not defined for $_"}); } | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		if ($errored) {return;} | 
		
	
		
			
				|  |  |  |  | 		#statelite | 
		
	
		
			
				|  |  |  |  | 		unless ($tempstate =~ /^netboot|^statelite/) { $chaintab->setNodeAttribs($_,{currchain=>"boot"}); }; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	     | 
		
	
		
			
				|  |  |  |  | 	    if ($action eq "reboot4deploy") { | 
		
	
		
			
				|  |  |  |  | 		# this action is used in the discovery process for deployment of the node | 
		
	
		
			
				|  |  |  |  | 		# e.g. set chain.chain to 'osimage=rhels6.2-x86_64-netboot-compute:reboot4deploy' | 
		
	
		
			
				|  |  |  |  | 		# Set the status of the node to be 'installing' or 'netbooting' | 
		
	
		
			
				|  |  |  |  | 		my %newnodestatus; | 
		
	
		
			
				|  |  |  |  | 		my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($tempstate, "rpower"); | 
		
	
		
			
				|  |  |  |  | 		$newnodestatus{$newstat}=$samestatenodes; | 
		
	
		
			
				|  |  |  |  | 		xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1); | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |     } elsif ($state eq "shell" or $state eq "standby" or $state =~ /^runcmd/ or $state =~ /^runimage/) { | 
		
	
		
			
				|  |  |  |  | 	$restab=xCAT::Table->new('noderes',-create=>1); | 
		
	
		
			
				|  |  |  |  | 	my $bootparms=xCAT::Table->new('bootparams',-create=>1); | 
		
	
		
			
				|  |  |  |  | 	my $nodetype = xCAT::Table->new('nodetype'); | 
		
	
		
			
				|  |  |  |  | 	#my $sitetab = xCAT::Table->new('site'); | 
		
	
		
			
				|  |  |  |  | 	my $nodehm = xCAT::Table->new('nodehm'); | 
		
	
		
			
				|  |  |  |  | 	my $hments = $nodehm->getNodesAttribs(\@nodes,['serialport','serialspeed','serialflow']); | 
		
	
		
			
				|  |  |  |  | 	#(my $portent) = $sitetab->getAttribs({key=>'xcatdport'},'value'); | 
		
	
		
			
				|  |  |  |  | 	my @entries =  xCAT::TableUtils->get_site_attribute("xcatdport"); | 
		
	
		
			
				|  |  |  |  | 	my $port_entry = $entries[0]; | 
		
	
		
			
				|  |  |  |  | 	#(my $mastent) = $sitetab->getAttribs({key=>'master'},'value'); | 
		
	
		
			
				|  |  |  |  | 	my @entries =  xCAT::TableUtils->get_site_attribute("master"); | 
		
	
		
			
				|  |  |  |  | 	my $master_entry = $entries[0]; | 
		
	
		
			
				|  |  |  |  | 	my $enthash = $nodetype->getNodesAttribs(\@nodes,[qw(arch)]); | 
		
	
		
			
				|  |  |  |  | 	my $resents = $restab->getNodeAttribs(\@nodes,[qw(xcatmaster)]); | 
		
	
		
			
				|  |  |  |  | 	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; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	    my $updateattribs; | 
		
	
		
			
				|  |  |  |  |             $updateattribs->{provmethod}=$target; | 
		
	
		
			
				|  |  |  |  |             $updateattribs->{profile}=$ref->{profile}; | 
		
	
		
			
				|  |  |  |  |             $updateattribs->{os}=$ref->{osvers}; | 
		
	
		
			
				|  |  |  |  |             $updateattribs->{arch}=$ref->{osarch}; | 
		
	
		
			
				|  |  |  |  |             my @tmpnodelist = @{$req->{node}}; | 
		
	
		
			
				|  |  |  |  |             $nodetypetable->setNodesAttribs(\@tmpnodelist,$updateattribs); | 
		
	
		
			
				|  |  |  |  |         } else {  | 
		
	
		
			
				|  |  |  |  |             $errored =1; $callback->({error=>"OS image name must be specified."}); | 
		
	
		
			
				|  |  |  |  | 	    return; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  |     # if precreatemypostscripts=1, create each mypostscript for each node | 
		
	
		
			
				|  |  |  |  |     # otherwise, create it during installation /updatenode | 
		
	
		
			
				|  |  |  |  |     require xCAT::Postage; | 
		
	
		
			
				|  |  |  |  |     xCAT::Postage::create_mypostscript_or_not($request, $callback, $subreq);         | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  | #print Dumper($req);  | 
		
	
		
			
				|  |  |  |  |     $errored=0; | 
		
	
		
			
				|  |  |  |  |     $subreq->({command=>["mk$state"], | 
		
	
		
			
				|  |  |  |  |               node=>$req->{node}}, \&relay_response); | 
		
	
		
			
				|  |  |  |  |     if ($errored) {  | 
		
	
		
			
				|  |  |  |  |         $callback->({error=>"Some nodes failed to set up $state resources, aborting"}); | 
		
	
		
			
				|  |  |  |  |         return; } | 
		
	
		
			
				|  |  |  |  |       | 
		
	
		
			
				|  |  |  |  |     my $ntents = $nodetypetable->getNodesAttribs($req->{node},[qw(os arch profile)]); | 
		
	
		
			
				|  |  |  |  |     foreach (@{$req->{node}}) { | 
		
	
		
			
				|  |  |  |  |       $nstates{$_} = $state; #local copy of state variable for mod | 
		
	
		
			
				|  |  |  |  |       my $ntent = $ntents->{$_}->[0]; #$nodetype->getNodeAttribs($_,[qw(os arch profile)]); | 
		
	
		
			
				|  |  |  |  |       if ($state ne "winshell") { | 
		
	
		
			
				|  |  |  |  |         if ($ntent and $ntent->{os}) { | 
		
	
		
			
				|  |  |  |  |             $nstates{$_} .= " ".$ntent->{os}; | 
		
	
		
			
				|  |  |  |  |         } else { $errored =1; $callback->({error=>"nodetype.os not defined for $_"}); } | 
		
	
		
			
				|  |  |  |  |       } else { | 
		
	
		
			
				|  |  |  |  |           $nstates{$_} .= " winpe"; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       if ($ntent and $ntent->{arch}) { | 
		
	
		
			
				|  |  |  |  |         $nstates{$_} .= "-".$ntent->{arch}; | 
		
	
		
			
				|  |  |  |  |       } else { $errored =1; $callback->({error=>"nodetype.arch not defined for $_"}); } | 
		
	
		
			
				|  |  |  |  |       if ($state ne "winshell") { | 
		
	
		
			
				|  |  |  |  |         if ($ntent and $ntent->{profile}) { | 
		
	
		
			
				|  |  |  |  |             $nstates{$_} .= "-".$ntent->{profile}; | 
		
	
		
			
				|  |  |  |  |           } else { $errored =1; $callback->({error=>"nodetype.profile not defined for $_"}); } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       if ($errored) {return;} | 
		
	
		
			
				|  |  |  |  | 	#statelite | 
		
	
		
			
				|  |  |  |  |       unless ($state =~ /^netboot|^statelite/) { $chaintab->setNodeAttribs($_,{currchain=>"boot"}); }; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if ($action eq "reboot4deploy") { | 
		
	
		
			
				|  |  |  |  |       # this action is used in the discovery process for deployment of the node | 
		
	
		
			
				|  |  |  |  |       # e.g. set chain.chain to 'osimage=rhels6.2-x86_64-netboot-compute:reboot4deploy' | 
		
	
		
			
				|  |  |  |  |       # Set the status of the node to be 'installing' or 'netbooting' | 
		
	
		
			
				|  |  |  |  |       my %newnodestatus; | 
		
	
		
			
				|  |  |  |  |       my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($state, "rpower"); | 
		
	
		
			
				|  |  |  |  |       $newnodestatus{$newstat}=$req->{node}; | 
		
	
		
			
				|  |  |  |  |       xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } elsif ($state eq "shell" or $state eq "standby" or $state =~ /^runcmd/ or $state =~ /^runimage/) { | 
		
	
		
			
				|  |  |  |  |     $restab=xCAT::Table->new('noderes',-create=>1); | 
		
	
		
			
				|  |  |  |  |     my $bootparms=xCAT::Table->new('bootparams',-create=>1); | 
		
	
		
			
				|  |  |  |  |     my $nodetype = xCAT::Table->new('nodetype'); | 
		
	
		
			
				|  |  |  |  |     #my $sitetab = xCAT::Table->new('site'); | 
		
	
		
			
				|  |  |  |  |     my $nodehm = xCAT::Table->new('nodehm'); | 
		
	
		
			
				|  |  |  |  |     my $hments = $nodehm->getNodesAttribs(\@nodes,['serialport','serialspeed','serialflow']); | 
		
	
		
			
				|  |  |  |  |     #(my $portent) = $sitetab->getAttribs({key=>'xcatdport'},'value'); | 
		
	
		
			
				|  |  |  |  |     my @entries =  xCAT::TableUtils->get_site_attribute("xcatdport"); | 
		
	
		
			
				|  |  |  |  |     my $port_entry = $entries[0]; | 
		
	
		
			
				|  |  |  |  |     #(my $mastent) = $sitetab->getAttribs({key=>'master'},'value'); | 
		
	
		
			
				|  |  |  |  |     my @entries =  xCAT::TableUtils->get_site_attribute("master"); | 
		
	
		
			
				|  |  |  |  |     my $master_entry = $entries[0]; | 
		
	
		
			
				|  |  |  |  |     my $enthash = $nodetype->getNodesAttribs(\@nodes,[qw(arch)]); | 
		
	
		
			
				|  |  |  |  |     my $resents = $restab->getNodeAttribs(\@nodes,[qw(xcatmaster)]); | 
		
	
		
			
				|  |  |  |  |     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; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       my $arch = $ent->{arch}; | 
		
	
		
			
				|  |  |  |  |       my $ent = $resents->{$_}->[0]; #$restab->getNodeAttribs($_,[qw(xcatmaster)]); | 
		
	
		
			
				|  |  |  |  |       my $master; | 
		
	
		
			
				|  |  |  |  |       my $kcmdline = "quiet "; | 
		
	
		
			
				|  |  |  |  |       if ( defined($master_entry) ) { | 
		
	
		
			
				|  |  |  |  |           $master = $master_entry; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       if ($ent and $ent->{xcatmaster}) { | 
		
	
		
			
				|  |  |  |  |           $master = $ent->{xcatmaster}; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       $ent = $hments->{$_}->[0]; #$nodehm->getNodeAttribs($_,['serialport','serialspeed','serialflow']); | 
		
	
		
			
				|  |  |  |  |       if ($ent and defined($ent->{serialport})) { | 
		
	
		
			
				|  |  |  |  |          $kcmdline .= "console=tty0 console=ttyS".$ent->{serialport}; | 
		
	
		
			
				|  |  |  |  |          #$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; | 
		
	
		
			
				|  |  |  |  |          } | 
		
	
		
			
				|  |  |  |  |          $kcmdline .= ",".$ent->{serialspeed}; | 
		
	
		
			
				|  |  |  |  |          #$ent = $nodehm->getNodeAttribs($_,['serialflow']); | 
		
	
		
			
				|  |  |  |  |          $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; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       if (-r "$tftpdir/xcat/genesis.kernel.$arch") { | 
		
	
		
			
				|  |  |  |  | 	  if (-r "$tftpdir/xcat/genesis.fs.$arch.lzma") { | 
		
	
		
			
				|  |  |  |  |           $bootparms->setNodeAttribs($_,{kernel => "xcat/genesis.kernel.$arch", | 
		
	
		
			
				|  |  |  |  |                                    initrd => "xcat/genesis.fs.$arch.lzma", | 
		
	
		
			
				|  |  |  |  |                                    kcmdline => $kcmdline."xcatd=$master:$xcatdport destiny=$state"}); | 
		
	
		
			
				|  |  |  |  | 	  } else { | 
		
	
		
			
				|  |  |  |  |           $bootparms->setNodeAttribs($_,{kernel => "xcat/genesis.kernel.$arch", | 
		
	
		
			
				|  |  |  |  |                                    initrd => "xcat/genesis.fs.$arch.gz", | 
		
	
		
			
				|  |  |  |  |                                    kcmdline => $kcmdline."xcatd=$master:$xcatdport destiny=$state"}); | 
		
	
		
			
				|  |  |  |  | 	    my $arch = $ent->{arch}; | 
		
	
		
			
				|  |  |  |  | 	    my $ent = $resents->{$_}->[0]; #$restab->getNodeAttribs($_,[qw(xcatmaster)]); | 
		
	
		
			
				|  |  |  |  | 	    my $master; | 
		
	
		
			
				|  |  |  |  | 	    my $kcmdline = "quiet "; | 
		
	
		
			
				|  |  |  |  | 	    if ( defined($master_entry) ) { | 
		
	
		
			
				|  |  |  |  | 		$master = $master_entry; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	    if ($ent and $ent->{xcatmaster}) { | 
		
	
		
			
				|  |  |  |  | 		$master = $ent->{xcatmaster}; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	    $ent = $hments->{$_}->[0]; #$nodehm->getNodeAttribs($_,['serialport','serialspeed','serialflow']); | 
		
	
		
			
				|  |  |  |  | 	    if ($ent and defined($ent->{serialport})) { | 
		
	
		
			
				|  |  |  |  | 		$kcmdline .= "console=tty0 console=ttyS".$ent->{serialport}; | 
		
	
		
			
				|  |  |  |  | 		#$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; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		$kcmdline .= ",".$ent->{serialspeed}; | 
		
	
		
			
				|  |  |  |  | 		#$ent = $nodehm->getNodeAttribs($_,['serialflow']); | 
		
	
		
			
				|  |  |  |  | 		$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; | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	    if (-r "$tftpdir/xcat/genesis.kernel.$arch") { | 
		
	
		
			
				|  |  |  |  | 		if (-r "$tftpdir/xcat/genesis.fs.$arch.lzma") { | 
		
	
		
			
				|  |  |  |  | 		    $bootparms->setNodeAttribs($_,{kernel => "xcat/genesis.kernel.$arch", | 
		
	
		
			
				|  |  |  |  | 						   initrd => "xcat/genesis.fs.$arch.lzma", | 
		
	
		
			
				|  |  |  |  | 						   kcmdline => $kcmdline."xcatd=$master:$xcatdport destiny=$state"}); | 
		
	
		
			
				|  |  |  |  | 		} else { | 
		
	
		
			
				|  |  |  |  | 		    $bootparms->setNodeAttribs($_,{kernel => "xcat/genesis.kernel.$arch", | 
		
	
		
			
				|  |  |  |  | 						   initrd => "xcat/genesis.fs.$arch.gz", | 
		
	
		
			
				|  |  |  |  | 						   kcmdline => $kcmdline."xcatd=$master:$xcatdport destiny=$state"}); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	    } else {  #'legacy' environment | 
		
	
		
			
				|  |  |  |  | 		$bootparms->setNodeAttribs($_,{kernel => "xcat/nbk.$arch", | 
		
	
		
			
				|  |  |  |  | 					       initrd => "xcat/nbfs.$arch.gz", | 
		
	
		
			
				|  |  |  |  | 					       kcmdline => $kcmdline."xcatd=$master:$xcatdport"}); | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |       } else {  #'legacy' environment | 
		
	
		
			
				|  |  |  |  |       $bootparms->setNodeAttribs($_,{kernel => "xcat/nbk.$arch", | 
		
	
		
			
				|  |  |  |  |                                    initrd => "xcat/nbfs.$arch.gz", | 
		
	
		
			
				|  |  |  |  |                                    kcmdline => $kcmdline."xcatd=$master:$xcatdport"}); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } elsif ($state eq "offline") { | 
		
	
		
			
				|  |  |  |  | 	1; | 
		
	
		
			
				|  |  |  |  |     } elsif (!($state eq "boot")) {  | 
		
	
		
			
				|  |  |  |  | 	$callback->({error=>["Unknown state $state requested"],errorcode=>[1]}); | 
		
	
		
			
				|  |  |  |  | 	return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } elsif ($state eq "offline") { | 
		
	
		
			
				|  |  |  |  |       1; | 
		
	
		
			
				|  |  |  |  |   } elsif (!($state eq "boot")) {  | 
		
	
		
			
				|  |  |  |  |       $callback->({error=>["Unknown state $state requested"],errorcode=>[1]}); | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   #blank out the nodetype.provmethod if the previous provisioning method is not 'install' | 
		
	
		
			
				|  |  |  |  |   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 @nodestoblank=(); | 
		
	
		
			
				|  |  |  |  |      my %osimage_hash=(); | 
		
	
		
			
				|  |  |  |  |      foreach (@{$req->{node}}) { | 
		
	
		
			
				|  |  |  |  | 	 my $ntent = $ntents->{$_}->[0]; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |          #if the previous nodeset staute is not install, then blank nodetype.provmethod | 
		
	
		
			
				|  |  |  |  | 	 if ($ntent and $ntent->{provmethod}){ | 
		
	
		
			
				|  |  |  |  | 	     my $provmethod=$ntent->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 	     if (($provmethod ne 'install') && ($provmethod ne 'netboot') && ($provmethod ne 'statelite')) { | 
		
	
		
			
				|  |  |  |  | 		 if (exists($osimage_hash{$provmethod})) { | 
		
	
		
			
				|  |  |  |  | 		     $provmethod= $osimage_hash{$provmethod}; | 
		
	
		
			
				|  |  |  |  | 		 } else { | 
		
	
		
			
				|  |  |  |  | 		     (my $ref) = $osimagetab->getAttribs({imagename => $provmethod}, 'provmethod'); | 
		
	
		
			
				|  |  |  |  | 		     if (($ref) && $ref->{provmethod}) { | 
		
	
		
			
				|  |  |  |  | 			 $osimage_hash{$provmethod}=$ref->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 			 $provmethod=$ref->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 		     }  | 
		
	
		
			
				|  |  |  |  | 		 } | 
		
	
		
			
				|  |  |  |  | 	     } | 
		
	
		
			
				|  |  |  |  | 	     if ($provmethod ne 'install') { | 
		
	
		
			
				|  |  |  |  | 		 push(@nodestoblank, $_); | 
		
	
		
			
				|  |  |  |  | 	     } | 
		
	
		
			
				|  |  |  |  | 	 } | 
		
	
		
			
				|  |  |  |  |      } #end foreach | 
		
	
		
			
				|  |  |  |  |       | 
		
	
		
			
				|  |  |  |  |      #now blank out the nodetype.provmethod | 
		
	
		
			
				|  |  |  |  |      #print "nodestoblank=@nodestoblank\n"; | 
		
	
		
			
				|  |  |  |  |      if (@nodestoblank > 0) { | 
		
	
		
			
				|  |  |  |  | 	 my $newhash; | 
		
	
		
			
				|  |  |  |  | 	 $newhash->{provmethod}=""; | 
		
	
		
			
				|  |  |  |  | 	 $nodetype->setNodesAttribs(\@nodestoblank, $newhash); | 
		
	
		
			
				|  |  |  |  |      } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if ($noupdate) { return; } #skip table manipulation if just doing 'enact' | 
		
	
		
			
				|  |  |  |  |   foreach (@nodes) { | 
		
	
		
			
				|  |  |  |  |     my $lstate = $state; | 
		
	
		
			
				|  |  |  |  |     if ($nstates{$_}) { | 
		
	
		
			
				|  |  |  |  |         $lstate = $nstates{$_}; | 
		
	
		
			
				|  |  |  |  |     }  | 
		
	
		
			
				|  |  |  |  |     $chaintab->setNodeAttribs($_,{currstate=>$lstate}); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return getdestiny($flag + 1); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     #blank out the nodetype.provmethod if the previous provisioning method is not 'install' | 
		
	
		
			
				|  |  |  |  |     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 @nodestoblank=(); | 
		
	
		
			
				|  |  |  |  | 	my %osimage_hash=(); | 
		
	
		
			
				|  |  |  |  | 	foreach (@{$req->{node}}) { | 
		
	
		
			
				|  |  |  |  | 	    my $ntent = $ntents->{$_}->[0]; | 
		
	
		
			
				|  |  |  |  | 	     | 
		
	
		
			
				|  |  |  |  | 	    #if the previous nodeset staute is not install, then blank nodetype.provmethod | 
		
	
		
			
				|  |  |  |  | 	    if ($ntent and $ntent->{provmethod}){ | 
		
	
		
			
				|  |  |  |  | 		my $provmethod=$ntent->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 		if (($provmethod ne 'install') && ($provmethod ne 'netboot') && ($provmethod ne 'statelite')) { | 
		
	
		
			
				|  |  |  |  | 		    if (exists($osimage_hash{$provmethod})) { | 
		
	
		
			
				|  |  |  |  | 			$provmethod= $osimage_hash{$provmethod}; | 
		
	
		
			
				|  |  |  |  | 		    } else { | 
		
	
		
			
				|  |  |  |  | 			(my $ref) = $osimagetab->getAttribs({imagename => $provmethod}, 'provmethod'); | 
		
	
		
			
				|  |  |  |  | 			if (($ref) && $ref->{provmethod}) { | 
		
	
		
			
				|  |  |  |  | 			    $osimage_hash{$provmethod}=$ref->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 			    $provmethod=$ref->{provmethod}; | 
		
	
		
			
				|  |  |  |  | 			}  | 
		
	
		
			
				|  |  |  |  | 		    } | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		if ($provmethod ne 'install') { | 
		
	
		
			
				|  |  |  |  | 		    push(@nodestoblank, $_); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	    } | 
		
	
		
			
				|  |  |  |  | 	} #end foreach | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	#now blank out the nodetype.provmethod | 
		
	
		
			
				|  |  |  |  | 	#print "nodestoblank=@nodestoblank\n"; | 
		
	
		
			
				|  |  |  |  | 	if (@nodestoblank > 0) { | 
		
	
		
			
				|  |  |  |  | 	    my $newhash; | 
		
	
		
			
				|  |  |  |  | 	    $newhash->{provmethod}=""; | 
		
	
		
			
				|  |  |  |  | 	    $nodetype->setNodesAttribs(\@nodestoblank, $newhash); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     if ($noupdate) { return; } #skip table manipulation if just doing 'enact' | 
		
	
		
			
				|  |  |  |  |     foreach (@nodes) { | 
		
	
		
			
				|  |  |  |  | 	my $lstate = $state; | 
		
	
		
			
				|  |  |  |  | 	if ($nstates{$_}) { | 
		
	
		
			
				|  |  |  |  | 	    $lstate = $nstates{$_}; | 
		
	
		
			
				|  |  |  |  | 	}  | 
		
	
		
			
				|  |  |  |  | 	$chaintab->setNodeAttribs($_,{currstate=>$lstate}); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     return getdestiny($flag + 1); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  |   |