| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -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);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |