git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@15037 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			1767 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1767 lines
		
	
	
		
			55 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| #!/usr/bin/env perl
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| package xCAT::SvrUtils;
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| require xCAT::Table;
 | |
| require xCAT::Utils;
 | |
| require xCAT::TableUtils;
 | |
| require xCAT::NetworkUtils;
 | |
| use File::Basename;
 | |
| use File::Path;
 | |
| 
 | |
| use strict;
 | |
| use Exporter;
 | |
| our @ISA = qw/Exporter/;
 | |
| our @EXPORT_OK = qw/sendmsg/;
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
|   
 | |
| 
 | |
| =head3   getNodesetStates
 | |
|        get current nodeset stat for the given nodes 
 | |
|     Arguments:
 | |
|         nodes -- a pointer to an array of nodes
 | |
|         hashref -- A pointer to a hash that contains the nodeset status.  
 | |
|     Returns:
 | |
|        (ret code, error message) 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub getNodesetStates
 | |
| {
 | |
|     my $noderef = shift;
 | |
|     if ($noderef =~ /xCAT::SvrUtils/)
 | |
|     {
 | |
|         $noderef = shift;
 | |
|     }
 | |
|     my @nodes   = @$noderef;
 | |
|     my $hashref = shift;
 | |
| 
 | |
|     if (@nodes > 0)
 | |
|     {
 | |
|         my $tab = xCAT::Table->new('noderes');
 | |
|         if (!$tab) { return (1, "Unable to open noderes table."); }
 | |
| 
 | |
|         my @aixnodes    = ();
 | |
|         my @pxenodes    = ();
 | |
|         my @yabootnodes = ();
 | |
|         my @xnbanodes= ();
 | |
|         my $tabdata     = $tab->getNodesAttribs(\@nodes, ['node', 'netboot']);
 | |
|         foreach my $node (@nodes)
 | |
|         {
 | |
|             my $nb   = "aixinstall";
 | |
|             my $tmp1 = $tabdata->{$node}->[0];
 | |
|             if (($tmp1) && ($tmp1->{netboot})) { $nb = $tmp1->{netboot}; }
 | |
|             if ($nb eq "yaboot")
 | |
|             {
 | |
|                 push(@yabootnodes, $node);
 | |
|             }
 | |
|             elsif ($nb eq "xnba")
 | |
|             {
 | |
|                 push(@xnbanodes, $node);
 | |
|             }
 | |
|             elsif ($nb eq "pxe")
 | |
|             {
 | |
|                 push(@pxenodes, $node);
 | |
|             }
 | |
|             elsif ($nb eq "aixinstall")
 | |
|             {
 | |
|                 push(@aixnodes, $node);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my @retarray;
 | |
|         my $retcode = 0;
 | |
|         my $errormsg;
 | |
| 
 | |
|         # print "ya=@yabootnodes, pxe=@pxenodes, aix=@aixnodes\n";
 | |
|         if (@yabootnodes > 0)
 | |
|         {
 | |
|             require xCAT_plugin::yaboot;
 | |
|             @retarray =
 | |
|               xCAT_plugin::yaboot::getNodesetStates(\@yabootnodes, $hashref);
 | |
|             if ($retarray[0])
 | |
|             {
 | |
|                 $retcode = $retarray[0];
 | |
|                 $errormsg .= $retarray[1];
 | |
|                 xCAT::MsgUtils->message('E', $retarray[1]);
 | |
|             }
 | |
|         }
 | |
|         if (@pxenodes > 0)
 | |
|         {
 | |
|             require xCAT_plugin::pxe;
 | |
|             @retarray =
 | |
|               xCAT_plugin::pxe::getNodesetStates(\@pxenodes, $hashref);
 | |
|             if ($retarray[0])
 | |
|             {
 | |
|                 $retcode = $retarray[0];
 | |
|                 $errormsg .= $retarray[1];
 | |
|                 xCAT::MsgUtils->message('E', $retarray[1]);
 | |
|             }
 | |
|         }
 | |
|         if (@xnbanodes > 0)
 | |
|         {
 | |
|             require xCAT_plugin::xnba;
 | |
|             @retarray =
 | |
|               xCAT_plugin::xnba::getNodesetStates(\@xnbanodes, $hashref);
 | |
|             if ($retarray[0])
 | |
|             {
 | |
|                 $retcode = $retarray[0];
 | |
|                 $errormsg .= $retarray[1];
 | |
|                 xCAT::MsgUtils->message('E', $retarray[1]);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (@aixnodes > 0)
 | |
|         {
 | |
|             require xCAT_plugin::aixinstall;
 | |
|             @retarray =
 | |
|               xCAT_plugin::aixinstall::getNodesetStates(\@aixnodes, $hashref);
 | |
|             if ($retarray[0])
 | |
|             {
 | |
|                 $retcode = $retarray[0];
 | |
|                 $errormsg .= $retarray[1];
 | |
|                 xCAT::MsgUtils->message('E', $retarray[1]);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   get_nodeset_state
 | |
|        get current nodeset stat for the given node.
 | |
|     Arguments:
 | |
|         nodes -- node name.
 | |
|     Returns:
 | |
|        nodesetstate 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub get_nodeset_state
 | |
| {
 | |
|     my $node = shift;
 | |
|     if ($node =~ /xCAT::SvrUtils/)
 | |
|     {
 | |
|         $node = shift;
 | |
|     }
 | |
|     my %options=@_;
 | |
|     my %gnopts;
 | |
|     if ($options{prefetchcache}) { $gnopts{prefetchcache}=1; }
 | |
| 
 | |
| 
 | |
|     my $state = "undefined";
 | |
|     my $tftpdir;
 | |
|     my $boottype;
 | |
|     if( %::GLOBAL_TAB_HASH && defined($::GLOBAL_TAB_HASH{noderes}) && defined($::GLOBAL_TAB_HASH{noderes}{$node}) ) {
 | |
|         $tftpdir = $::GLOBAL_TAB_HASH{noderes}{$node}{tftpdir};
 | |
|         $boottype = $::GLOBAL_TAB_HASH{noderes}{$node}{netboot};
 | |
|         
 | |
|     } else {
 | |
|         #get boot type (pxe, yaboot or aixinstall)  for the node
 | |
|         my $noderestab = xCAT::Table->new('noderes', -create => 0);
 | |
|         my $ent = $noderestab->getNodeAttribs($node, [qw(netboot tftpdir)],%gnopts);
 | |
| 
 | |
|         #get tftpdir from the noderes table, if not defined get it from site talbe
 | |
|         if ($ent && $ent->{tftpdir}) {
 | |
| 	    $tftpdir=$ent->{tftpdir};
 | |
|         }
 | |
|         if (!$tftpdir) {
 | |
| 	    if ($::XCATSITEVALS{tftpdir}) { 
 | |
| 	        $tftpdir=$::XCATSITEVALS{tftpdir};
 | |
| 	    }
 | |
|         }
 | |
| 
 | |
|         if ($ent && $ent->{netboot})
 | |
|         {
 | |
|             $boottype = $ent->{netboot};
 | |
|         }
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
|     if ( defined($boottype) )
 | |
|     {
 | |
|         #my $boottype = $ent->{netboot};
 | |
| 
 | |
|         #get nodeset state from corresponding files
 | |
|         if ($boottype eq "pxe")
 | |
|         {
 | |
|             require xCAT_plugin::pxe;
 | |
|             my $tmp = xCAT_plugin::pxe::getstate($node, $tftpdir);
 | |
|             my @a = split(' ', $tmp);
 | |
|             $state = $a[0];
 | |
|         }
 | |
|         elsif ($boottype eq "xnba")
 | |
|         {
 | |
|             require xCAT_plugin::xnba;
 | |
|             my $tmp = xCAT_plugin::xnba::getstate($node, $tftpdir);
 | |
|             my @a = split(' ', $tmp);
 | |
|             $state = $a[0];
 | |
|         }
 | |
|         elsif ($boottype eq "yaboot")
 | |
|         {
 | |
|             require xCAT_plugin::yaboot;
 | |
|             my $tmp = xCAT_plugin::yaboot::getstate($node, $tftpdir);
 | |
|             my @a = split(' ', $tmp);
 | |
|             $state = $a[0];
 | |
|         }
 | |
|         elsif ($boottype eq "aixinstall")
 | |
|         {
 | |
|             require xCAT_plugin::aixinstall;
 | |
|             $state = xCAT_plugin::aixinstall::getNodesetState($node);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {    #default to AIX because AIX does not set noderes.netboot value
 | |
|         require xCAT_plugin::aixinstall;
 | |
|         $state = xCAT_plugin::aixinstall::getNodesetState($node);
 | |
|     }
 | |
|     
 | |
|     #get the nodeset state from the chain table as a backup.
 | |
|     if ($state eq "undefined")
 | |
|     {
 | |
|         my $chaintab = xCAT::Table->new('chain');
 | |
|         my $stref = $chaintab->getNodeAttribs($node, ['currstate'],%gnopts);
 | |
|         if ($stref and $stref->{currstate}) { $state = $stref->{currstate}; }
 | |
|     }
 | |
| 
 | |
|     return $state;
 | |
| }
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| =head3 getsynclistfile
 | |
|     Get the synclist file for the nodes;
 | |
|     The arguments $os,$arch,$profile,$insttype are only available when no $nodes is specified
 | |
| 
 | |
|     Arguments:
 | |
|       $nodes
 | |
|       $os
 | |
|       $arch
 | |
|       $profile
 | |
|       $insttype  - installation type (can be install or netboot)
 | |
|     Returns:
 | |
|       When specified $nodes: reference of a hash of node=>synclist
 | |
|       Otherwise: full path of the synclist file
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|     Example:
 | |
|          my $node_syncfile=xCAT::SvrUtils->getsynclistfile($nodes);
 | |
|          my $syncfile=xCAT::SvrUtils->getsynclistfile(undef, 'sles11', 'ppc64', 'compute', 'netboot');
 | |
|     Comments:
 | |
|         none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| sub getsynclistfile()
 | |
| {
 | |
|   my $nodes = shift;
 | |
|   if (($nodes) && ($nodes =~ /xCAT::SvrUtils/))
 | |
|   {
 | |
|     $nodes = shift;
 | |
|   }
 | |
| 
 | |
|   my ($os, $arch, $profile, $inst_type, $imgname) = @_;
 | |
| 
 | |
|   my $installdir = xCAT::TableUtils->getInstallDir();
 | |
| 
 | |
|   # for aix node, use the node figure out the profile, then use the value of
 | |
|   # profile (osimage name) to get the synclist file path (osimage.synclists)
 | |
|   if (xCAT::Utils->isAIX()) {
 | |
|     my %node_syncfile = ();
 | |
|     my %osimage_syncfile = ();
 | |
|     my @profiles = ();
 | |
| 
 | |
|     if ($nodes) {
 | |
| 	# get the profile attributes for the nodes
 | |
| 	my $nodetype_t = xCAT::Table->new('nodetype');
 | |
| 	unless ($nodetype_t) {
 | |
| 	    return ;
 | |
| 	}
 | |
| 	my $nodetype_v = $nodetype_t->getNodesAttribs($nodes, ['profile', 'provmethod']);
 | |
| 	
 | |
| 	# the vaule of profile for AIX node is the osimage name
 | |
| 	foreach my $node (@$nodes) {
 | |
| 	    my $profile = $nodetype_v->{$node}->[0]->{'profile'};
 | |
| 	    my $provmethod=$nodetype_v->{$node}->[0]->{'provmethod'};
 | |
| 	    if ($provmethod) {
 | |
| 		$profile=$provmethod;
 | |
| 	    }
 | |
| 	    
 | |
| 	    $node_syncfile{$node} = $profile;
 | |
| 	    
 | |
| 	    if (! grep /$profile/, @profiles) {
 | |
| 		push @profiles, $profile;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     # get the syncfiles base on the osimage
 | |
|     my $osimage_t = xCAT::Table->new('osimage');
 | |
|     unless ($osimage_t) {
 | |
|       return ;
 | |
|     }
 | |
|     foreach my $osimage (@profiles) {
 | |
|       my $synclist = $osimage_t->getAttribs({imagename=>"$osimage"}, 'synclists');
 | |
|       $osimage_syncfile{$osimage} = $synclist->{'synclists'};
 | |
|     }
 | |
| 
 | |
|     # set the syncfiles to the nodes
 | |
|     foreach my $node (@$nodes) {
 | |
|       $node_syncfile{$node} = $osimage_syncfile{$node_syncfile{$node}};
 | |
|     }
 | |
| 
 | |
|     return \%node_syncfile;
 | |
|   } # end isAIX
 | |
| 
 | |
|   # if does not specify the $node param, default consider for genimage command
 | |
|   if ($nodes) {
 | |
|     my %node_syncfile = ();
 | |
| 
 | |
|     # get the os,arch,profile attributes for the nodes
 | |
|     my $nodetype_t = xCAT::Table->new('nodetype');
 | |
|     unless ($nodetype_t) {
 | |
|       return ;
 | |
|     }
 | |
|     my $nodetype_v = $nodetype_t->getNodesAttribs($nodes, ['profile','os','arch','provmethod']);
 | |
| 
 | |
| 	  my $osimage_t = xCAT::Table->new('osimage');
 | |
| 	  unless ($osimage_t) {
 | |
| 	      return ;
 | |
| 	  }
 | |
|     foreach my $node (@$nodes) {
 | |
|       my $provmethod=$nodetype_v->{$node}->[0]->{'provmethod'};
 | |
|       if (($provmethod) && ( $provmethod ne "install") && ($provmethod ne "netboot") && ($provmethod ne "statelite")) {
 | |
| 	  # get the syncfiles base on the osimage
 | |
| 	  my $synclist = $osimage_t->getAttribs({imagename=>$provmethod}, 'synclists');
 | |
| 	  if ($synclist && $synclist->{'synclists'}) {
 | |
| 	      $node_syncfile{$node} = $synclist->{'synclists'};
 | |
| 	  }  
 | |
|       } else {
 | |
| 	  $inst_type = "install";
 | |
| 	  if ($provmethod eq "netboot" || $provmethod eq "diskless" || $provmethod eq "statelite") {
 | |
| 	      $inst_type = "netboot";
 | |
| 	  } 
 | |
| 	  
 | |
| 	  $profile = $nodetype_v->{$node}->[0]->{'profile'};
 | |
| 	  $os = $nodetype_v->{$node}->[0]->{'os'};
 | |
| 	  $arch = $nodetype_v->{$node}->[0]->{'arch'};
 | |
| 	  my $platform = "";
 | |
| 	  if ($os) {
 | |
| 	      if ($os =~ /rh.*/)    { $platform = "rh"; }
 | |
| 	      elsif ($os =~ /centos.*/) { $platform = "centos"; }
 | |
| 	      elsif ($os =~ /fedora.*/) { $platform = "fedora"; }
 | |
| 	      elsif ($os =~ /sles.*/) { $platform = "sles"; }
 | |
| 	      elsif ($os =~ /SL.*/) { $platform = "SL"; }
 | |
| 	      elsif ($os =~ /ubuntu.*/) { $platform = "ubuntu"; }
 | |
| 	      elsif ($os =~ /debian.*/) { $platform = "debian"; }
 | |
| 	      elsif ($os =~ /AIX.*/) { $platform = "AIX"; }
 | |
| 	  }
 | |
| 
 | |
| 	  my $base =  "$installdir/custom/$inst_type/$platform";
 | |
| 	  $node_syncfile{$node} = xCAT::SvrUtils::get_file_name($base, "synclist", $profile, $os, $arch);	 
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return \%node_syncfile;
 | |
|   } else {
 | |
|     if ($imgname) {
 | |
|         my $osimage_t = xCAT::Table->new('osimage');
 | |
|         unless ($osimage_t) {
 | |
|             return ;
 | |
|         }
 | |
|         my $synclist = $osimage_t->getAttribs({imagename=>$imgname}, 'synclists');
 | |
|         if ($synclist && $synclist->{'synclists'}) {
 | |
|             return $synclist->{'synclists'};
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     my $platform = "";
 | |
|     if ($os) {
 | |
|       if ($os =~ /rh.*/)    { $platform = "rh"; }
 | |
|       elsif ($os =~ /centos.*/) { $platform = "centos"; }
 | |
|       elsif ($os =~ /fedora.*/) { $platform = "fedora"; }
 | |
|       elsif ($os =~ /sles.*/) { $platform = "sles"; }
 | |
|       elsif ($os =~ /SL.*/) { $platform = "SL"; }
 | |
|       elsif ($os =~ /ubuntu.*/) { $platform = "ubuntu"; }
 | |
|       elsif ($os =~ /debian.*/) { $platform = "debian"; }
 | |
|       elsif ($os =~ /AIX.*/) { $platform = "AIX"; }
 | |
|       elsif ($os =~ /win/)  {$platform = "windows"; }
 | |
|     }
 | |
| 
 | |
|     my $base = "$installdir/custom/$inst_type/$platform";
 | |
|     return xCAT::SvrUtils::get_file_name($base, "synclist", $profile, $os, $arch);
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| sub get_file_name {
 | |
|     my ($searchpath, $extension, $profile, $os, $arch, $genos) = @_;
 | |
|     #usally there're only 4 arguments passed for this function
 | |
|     #the $genos is only used for the Redhat family
 | |
| 
 | |
|     my $dotpos = rindex($os, ".");
 | |
|     my $osbase = substr($os, 0, $dotpos);
 | |
|     #handle the following ostypes: sles10.2, sles11.1, rhels5.3, rhels5.4, etc
 | |
| 
 | |
|     if (-r "$searchpath/$profile.$os.$arch.$extension") {
 | |
|         return "$searchpath/$profile.$os.$arch.$extension";
 | |
|     }
 | |
|     elsif (-r "$searchpath/$profile.$osbase.$arch.$extension") {
 | |
|         return "$searchpath/$profile.$osbase.$arch.$extension";
 | |
|     }
 | |
|     elsif (-r "$searchpath/$profile.$genos.$arch.$extension") {
 | |
|         return "$searchpath/$profile.$genos.$arch.$extension";
 | |
|     }
 | |
|     elsif (-r "$searchpath/$profile.$os.$extension") {
 | |
|         return "$searchpath/$profile.$os.$extension";
 | |
|     }
 | |
|     elsif (-r "$searchpath/$profile.$osbase.$extension") {
 | |
|         return "$searchpath/$profile.$osbase.$extension";
 | |
|     }
 | |
|     elsif (-r "$searchpath/$profile.$genos.$extension") {
 | |
|         return "$searchpath/$profile.$genos.$extension";
 | |
|     }
 | |
|     elsif (-r "$searchpath/$profile.$arch.$extension") {
 | |
|         return "$searchpath/$profile.$arch.$extension";
 | |
|     }
 | |
|     elsif (-r "$searchpath/$profile.$extension") {
 | |
|         return "$searchpath/$profile.$extension";
 | |
|     }
 | |
|     else {
 | |
|         return undef;
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub get_tmpl_file_name {
 | |
|     my $searchpath=shift;
 | |
|     if (($searchpath) && ($searchpath =~ /xCAT::SvrUtils/)) {
 | |
| 	$searchpath = shift;
 | |
|     }
 | |
|     return xCAT::SvrUtils::get_file_name($searchpath, "tmpl", @_);
 | |
| }
 | |
| 
 | |
| 
 | |
| sub get_pkglist_file_name {
 | |
|     my $searchpath=shift;
 | |
|     if (($searchpath) && ($searchpath =~ /xCAT::SvrUtils/)) {
 | |
| 	$searchpath = shift;
 | |
|     }
 | |
|     return xCAT::SvrUtils::get_file_name($searchpath, "pkglist", @_);
 | |
| }
 | |
| 
 | |
| sub get_otherpkgs_pkglist_file_name {
 | |
|     my $searchpath=shift;
 | |
|     if (($searchpath) && ($searchpath =~ /xCAT::SvrUtils/)) {
 | |
| 	$searchpath = shift;
 | |
|     }
 | |
|     return xCAT::SvrUtils::get_file_name($searchpath, "otherpkgs.pkglist", @_);
 | |
| }
 | |
| 
 | |
| 
 | |
| sub get_postinstall_file_name {
 | |
|     my $searchpath=shift;
 | |
|     if (($searchpath) && ($searchpath =~ /xCAT::SvrUtils/)) {
 | |
| 	$searchpath = shift;
 | |
|     }
 | |
|     my $profile=shift;
 | |
|     my $os=shift;
 | |
|     my $arch=shift;
 | |
|     my $extension="postinstall";
 | |
|     my $dotpos = rindex($os, ".");
 | |
|     my $osbase = substr($os, 0, $dotpos);
 | |
|     #handle the following ostypes: sles10.2, sles11.1, rhels5.3, rhels5.4, etc
 | |
| 
 | |
|     if (-x "$searchpath/$profile.$os.$arch.$extension") {
 | |
|         return "$searchpath/$profile.$os.$arch.$extension";
 | |
|     }
 | |
|     elsif (-x "$searchpath/$profile.$osbase.$arch.$extension") {
 | |
|         return "$searchpath/$profile.$osbase.$arch.$extension";
 | |
|     }
 | |
|     elsif (-x "$searchpath/$profile.$os.$extension") {
 | |
|         return "$searchpath/$profile.$os.$extension";
 | |
|     }
 | |
|     elsif (-x "$searchpath/$profile.$osbase.$extension") {
 | |
|         return "$searchpath/$profile.$osbase.$extension";
 | |
|     }
 | |
|     elsif (-x "$searchpath/$profile.$arch.$extension") {
 | |
|         return "$searchpath/$profile.$arch.$extension";
 | |
|     }
 | |
|     elsif (-x "$searchpath/$profile.$extension") {
 | |
|         return "$searchpath/$profile.$extension";
 | |
|     }
 | |
|     else {
 | |
|         return undef;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| sub get_exlist_file_name {
 | |
|     my $searchpath=shift;
 | |
|     if (($searchpath) && ($searchpath =~ /xCAT::SvrUtils/)) {
 | |
| 	$searchpath = shift;
 | |
|     }
 | |
|     return xCAT::SvrUtils::get_file_name($searchpath, "exlist", @_);
 | |
| }
 | |
| 
 | |
| # for the "imgcapture" command
 | |
| 
 | |
| sub get_imgcapture_exlist_file_name {
 | |
|     my $searchpath = shift;
 | |
|     if ($searchpath and $searchpath =~ m/xCAT::SvrUtils/) {
 | |
|         $searchpath = shift;
 | |
|     }
 | |
|     return xCAT::SvrUtils::get_file_name($searchpath, "imgcapture.exlist", @_);
 | |
| }
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   update_tables_with_templates
 | |
|        This function is called after copycds. Itwill get all the possible install templates
 | |
|        from the default directories for the given osver and arch and update the osimage table.
 | |
|     Arguments:
 | |
|         osver
 | |
|         arch
 | |
| 	ospkgdir
 | |
| 	osdistroname
 | |
|     Returns:
 | |
|         an array (retcode, errmsg). The first one is the return code. If 0, it means succesful. 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub  update_tables_with_templates
 | |
| {
 | |
|     my $osver = shift;  #like sle11, rhel5.3 
 | |
|     if (($osver) && ($osver =~ /xCAT::SvrUtils/)) {
 | |
| 	$osver = shift;
 | |
|     }
 | |
|     my $arch = shift;  #like ppc64, x86, x86_64
 | |
|     my $ospkgdir=shift;      
 | |
|     my $osdistroname=shift;
 | |
| 
 | |
|     my $osname=$osver;;  #like sles, rh, centos, windows
 | |
|     my $ostype="Linux";  #like Linux, Windows
 | |
|     my $imagetype="linux";
 | |
|     if (($osver =~ /^win/) || ($osver =~ /^imagex/)) {
 | |
| 	$osname="windows";
 | |
| 	$ostype="Windows";
 | |
|         $imagetype="windows";
 | |
|     } elsif ($osver =~ /^hyperv/) {
 | |
| 	$osname="hyperv";
 | |
| 	$ostype="Windows";
 | |
|         $imagetype="windows";
 | |
|     } else {
 | |
| 	until (-r  "$::XCATROOT/share/xcat/install/$osname/" or not $osname) {
 | |
| 	    chop($osname);
 | |
|         }
 | |
|         unless ($osname) {
 | |
| 	    return (1, "Unable to find $::XCATROOT/share/xcat/install directory for $osver");
 | |
| 	}  
 | |
|     } 
 | |
|       
 | |
|     #for rhels5.1  genos=rhel5
 | |
|     my $genos = $osver;
 | |
|     $genos =~ s/\..*//;
 | |
|     if ($genos =~ /rh.*s(\d*)/) {
 | |
| 	$genos = "rhel$1";
 | |
|     }
 | |
| 
 | |
|   
 | |
|     #print "osver=$osver, arch=$arch, osname=$osname, genos=$genos\n";
 | |
|     my $installroot = xCAT::TableUtils->getInstallDir();
 | |
|     #my $sitetab = xCAT::Table->new('site');
 | |
|     #if ($sitetab) {
 | |
|     #	(my $ref) = $sitetab->getAttribs({key => "installdir"}, "value");
 | |
|     #	if ($ref and $ref->{value}) {
 | |
|     #       $installroot = $ref->{value};
 | |
|     #	}
 | |
|     #}
 | |
|     my @installdirs = xCAT::TableUtils->get_site_attribute("installdir");
 | |
|     my $tmp = $installdirs[0];
 | |
|     if ( defined($tmp)) {
 | |
|        $installroot = $tmp; 
 | |
|     }
 | |
|     my $cuspath="$installroot/custom/install/$osname";
 | |
|     my $defpath="$::XCATROOT/share/xcat/install/$osname"; 
 | |
|     
 | |
|     #now get all the profile names for full installation
 | |
|     my %profiles=();
 | |
|     my @tmplfiles=glob($cuspath."/*.tmpl");
 | |
|     foreach (@tmplfiles) {
 | |
| 	my $tmpf=basename($_); 
 | |
| 	#get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
 | |
| 	$tmpf =~ /^([^\.]*)\..*$/;
 | |
| 	$tmpf = $1;
 | |
| 	#print "$tmpf\n";
 | |
| 	$profiles{$tmpf}=1;
 | |
|     }
 | |
|     @tmplfiles=glob($defpath."/*.tmpl");
 | |
|     foreach (@tmplfiles) {
 | |
| 	my $tmpf=basename($_); 
 | |
| 	#get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
 | |
| 	$tmpf =~ /^([^\.]*)\..*$/;
 | |
| 	$tmpf = $1;
 | |
| 	$profiles{$tmpf}=1;
 | |
|     }
 | |
|     
 | |
|     #update the osimage and linuximage table
 | |
|     my $osimagetab;
 | |
|     my $linuximagetab;
 | |
|     foreach my $profile (keys %profiles) {
 | |
| 	#print "profile=$profile\n";
 | |
| 	#get template file
 | |
| 	my $tmplfile=get_tmpl_file_name ($cuspath, $profile, $osver, $arch, $genos);
 | |
| 	if (!$tmplfile) { $tmplfile=get_tmpl_file_name ($defpath, $profile, $osver, $arch, $genos);}
 | |
| 	if (!$tmplfile) { next; }
 | |
| 	
 | |
| 	#get otherpkgs.pkglist file
 | |
| 	my $otherpkgsfile=get_otherpkgs_pkglist_file_name($cuspath, $profile, $osver, $arch);
 | |
| 	if (!$otherpkgsfile) { $otherpkgsfile=get_otherpkgs_pkglist_file_name($defpath, $profile, $osver, $arch);}
 | |
| 	
 | |
| 	#get synclist file
 | |
| 	my $synclistfile=xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot");
 | |
| 	
 | |
| 	#get the pkglist file
 | |
| 	my $pkglistfile=get_pkglist_file_name($cuspath, $profile, $osver, $arch);
 | |
| 	if (!$pkglistfile) { $pkglistfile=get_pkglist_file_name($defpath, $profile, $osver, $arch);}
 | |
| 
 | |
| 	#now update the db
 | |
| 	if (!$osimagetab) { 
 | |
| 	    $osimagetab=xCAT::Table->new('osimage',-create=>1); 
 | |
| 	}
 | |
| 
 | |
| 	if ($osimagetab) {    
 | |
| 	    #check if the image is already in the table
 | |
| 	    if ($osimagetab) {
 | |
| 		my $found=0;
 | |
| 		my $tmp1=$osimagetab->getAllEntries();
 | |
| 		if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
| 		    foreach my $rowdata(@$tmp1) {
 | |
| 			if (($osver eq $rowdata->{osvers}) && ($arch eq $rowdata->{osarch}) && ($rowdata->{provmethod} eq "install") && ($profile eq $rowdata->{profile})){
 | |
| 			    $found=1;
 | |
| 			    last;
 | |
| 			}
 | |
| 		    }
 | |
| 		}
 | |
| #		if ($found) { next; } 
 | |
| 
 | |
| 		my $imagename=$osver . "-" . $arch . "-install-" . $profile;
 | |
|                 #TODO: check if there happen to be a row that has the same imagename but with different contents
 | |
|                 #now we can wirte the info into db
 | |
| 		my %key_col = (imagename=>$imagename);
 | |
| 		my %tb_cols=(imagetype=>$imagetype,
 | |
| 			     provmethod=>"install",
 | |
| 			     profile=>$profile, 
 | |
| 			     osname=>$ostype,
 | |
| 			     osvers=>$osver,
 | |
| 			     osarch=>$arch,
 | |
| 			     synclists=>$synclistfile,
 | |
| 			     osdistroname=>$osdistroname);
 | |
| 		$osimagetab->setAttribs(\%key_col, \%tb_cols);
 | |
|                 
 | |
| 		if ($osname !~ /^win/) {
 | |
| 		    if (!$linuximagetab) { $linuximagetab=xCAT::Table->new('linuximage',-create=>1); }
 | |
| 		    if ($linuximagetab) {
 | |
| 			my %key_col = (imagename=>$imagename);
 | |
| 			my %tb_cols=(template=>$tmplfile, 
 | |
| 				     pkgdir=>$ospkgdir,
 | |
| 				     pkglist=>$pkglistfile,
 | |
| 				     otherpkglist=>$otherpkgsfile,
 | |
| 				     otherpkgdir=>"$installroot/post/otherpkgs/$osver/$arch");
 | |
| 			$linuximagetab->setAttribs(\%key_col, \%tb_cols);
 | |
| 			
 | |
| 		    } else {
 | |
| 			return (1, "Cannot open the linuximage table.");
 | |
| 		    }
 | |
| 		}
 | |
| 	    } else {
 | |
| 		return (1, "Cannot open the osimage table."); 
 | |
| 	    }
 | |
| 	}  
 | |
|     }
 | |
|     if ($osimagetab) { $osimagetab->close(); }
 | |
|     if ($linuximagetab) { $linuximagetab->close(); }
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   update_tables_with_diskless_image
 | |
|        This function is called after a diskless image is created by packimage.
 | |
|     It'll writes the newimage info into the osimage and the linuximage tables.
 | |
|     Arguments:
 | |
|         osver
 | |
|         arch
 | |
|         profile
 | |
|         mode
 | |
|         ospkgdir
 | |
|     Returns:
 | |
|         an array (retcode, errmsg). The first one is the return code. If 0, it means succesful. 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub  update_tables_with_diskless_image
 | |
| {
 | |
|     my $osver = shift;  #like sle11, rhel5.3 
 | |
|     if (($osver) && ($osver =~ /xCAT::SvrUtils/)) {
 | |
| 	$osver = shift;
 | |
|     }
 | |
|     my $arch = shift;  #like ppc64, x86, x86_64
 | |
|     my $profile = shift;
 | |
|     my $mode=shift;
 | |
|     my $ospkgdir=shift;
 | |
|     my $osdistroname=shift; 
 | |
| 
 | |
|     my $provm="netboot";
 | |
|     if ($mode) { $provm = $mode; } 
 | |
|     
 | |
|     my $osname=$osver;;  #like sles, rh, centos, windows
 | |
|     my $ostype="Linux";  #like Linux, Windows
 | |
|     my $imagetype="linux";
 | |
|     if (($osver =~ /^win/) || ($osver =~ /^imagex/)) {
 | |
| 	$osname="windows";
 | |
| 	$ostype="Windows";
 | |
| 	$imagetype="windows";
 | |
|     } else {
 | |
| 	until (-r  "$::XCATROOT/share/xcat/netboot/$osname/" or not $osname) {
 | |
| 	    chop($osname);
 | |
|         }
 | |
|         unless ($osname) {
 | |
| 	    return (1, "Unable to find $::XCATROOT/share/xcat/netboot directory for $osver");
 | |
| 	}  
 | |
|     } 
 | |
|       
 | |
|     #for rhels5.1  genos=rhel5
 | |
|     my $genos = $osver;
 | |
|     $genos =~ s/\..*//;
 | |
|     if ($genos =~ /rh.*s(\d*)/) {
 | |
| 	$genos = "rhel$1";
 | |
|     }
 | |
|   
 | |
|     #print "osver=$osver, arch=$arch, osname=$osname, genos=$genos, profile=$profile\n";
 | |
|     my $installroot = xCAT::TableUtils->getInstallDir();
 | |
|     #my $sitetab = xCAT::Table->new('site');
 | |
|     #if ($sitetab) {
 | |
|     #	(my $ref) = $sitetab->getAttribs({key => "installdir"}, "value");
 | |
|     #	if ($ref and $ref->{value}) {
 | |
|     #	    $installroot = $ref->{value};
 | |
|     #	}
 | |
|     #}
 | |
|     my @installdirs = xCAT::TableUtils->get_site_attribute("installdir");
 | |
|     my $tmp = $installdirs[0];
 | |
|     if ( defined($tmp)) {
 | |
|        $installroot = $tmp; 
 | |
|     }
 | |
|     my $cuspath="$installroot/custom/netboot/$osname";
 | |
|     my $defpath="$::XCATROOT/share/xcat/netboot/$osname"; 
 | |
|     my $osimagetab;
 | |
|     my $linuximagetab;
 | |
| 
 | |
|     my %profiles=();
 | |
|     if ($profile) {
 | |
|         $profiles{$profile} = 1;
 | |
|     } else {
 | |
|         my @tmplfiles=glob($cuspath."/*.pkglist");
 | |
|         foreach (@tmplfiles) {
 | |
|             my $tmpf=basename($_); 
 | |
|             #get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
 | |
|             $tmpf =~ /^([^\.]*)\..*$/;
 | |
|             $tmpf = $1;
 | |
|             $profiles{$tmpf}=1;
 | |
|         }
 | |
|         @tmplfiles=glob($defpath."/*.pkglist");
 | |
|         foreach (@tmplfiles) {
 | |
|             my $tmpf=basename($_); 
 | |
|             #get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
 | |
|             $tmpf =~ /^([^\.]*)\..*$/;
 | |
|             $tmpf = $1;
 | |
|             $profiles{$tmpf}=1;
 | |
|         }
 | |
|     }
 | |
|     foreach my $profile (keys %profiles) {
 | |
|         #get the pkglist file
 | |
|         my $pkglistfile=get_pkglist_file_name($cuspath, $profile, $osver, $arch);
 | |
|         if (!$pkglistfile) { $pkglistfile=get_pkglist_file_name($defpath, $profile, $osver, $arch);}
 | |
|         #print "pkglistfile=$pkglistfile\n";
 | |
|         if (!$pkglistfile) { next;}
 | |
|         
 | |
|         #get otherpkgs.pkglist file
 | |
|         my $otherpkgsfile=get_otherpkgs_pkglist_file_name($cuspath, $profile, $osver, $arch);
 | |
|         if (!$otherpkgsfile) { $otherpkgsfile=get_otherpkgs_pkglist_file_name($defpath, $profile, $osver, $arch);}
 | |
|         
 | |
|         #get synclist file
 | |
|         my $synclistfile=xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot");
 | |
|         
 | |
|         #get the exlist file
 | |
|         my $exlistfile=get_exlist_file_name($cuspath, $profile, $osver, $arch);
 | |
|         if (!$exlistfile) {  $exlistfile=get_exlist_file_name($defpath, $profile, $osver, $arch); }
 | |
|     
 | |
|         #get postinstall script file name
 | |
|         my $postfile=get_postinstall_file_name($cuspath, $profile, $osver, $arch);
 | |
|         if (!$postfile) {  $postfile=get_postinstall_file_name($defpath, $profile, $osver, $arch); }
 | |
|     
 | |
|     
 | |
|         #now update the db
 | |
|         if (!$osimagetab) { 
 | |
|     	$osimagetab=xCAT::Table->new('osimage',-create=>1); 
 | |
|         }
 | |
|         
 | |
|         if ($osimagetab) {    
 | |
|     	#check if the image is already in the table
 | |
|     	if ($osimagetab) {
 | |
|     	    my $found=0;
 | |
|     	    my $tmp1=$osimagetab->getAllEntries();
 | |
|     	    if (defined($tmp1) && (@$tmp1 > 0)) {
 | |
|     		foreach my $rowdata(@$tmp1) {
 | |
|     		    if (($osver eq $rowdata->{osvers}) && ($arch eq $rowdata->{osarch}) && ($rowdata->{provmethod} eq $provm) && ($profile eq $rowdata->{profile})){
 | |
|     			$found=1;
 | |
|     			last;
 | |
|     		    }
 | |
|     		}
 | |
|     	    }
 | |
|            if ($found) { 
 | |
|                            print "The image is already in the db.\n"; 
 | |
|  #                         next; 
 | |
|                          } 
 | |
|     	    
 | |
|     	    my $imagename=$osver . "-" . $arch . "-$provm-" . $profile;
 | |
|     	    #TODO: check if there happen to be a row that has the same imagename but with different contents
 | |
|     	    #now we can wirte the info into db
 | |
|     	    my %key_col = (imagename=>$imagename);
 | |
|     	    my %tb_cols=(imagetype=>$imagetype, 
 | |
|     			 provmethod=>$provm,
 | |
|     			 profile=>$profile, 
 | |
|     			 osname=>$ostype,
 | |
|     			 osvers=>$osver,
 | |
|     			 osarch=>$arch,
 | |
|     			 synclists=>$synclistfile,
 | |
| 			 osdistroname=>$osdistroname);
 | |
|     	    $osimagetab->setAttribs(\%key_col, \%tb_cols);
 | |
|     	    
 | |
|     	    if ($osname !~ /^win/) {
 | |
|     		if (!$linuximagetab) { $linuximagetab=xCAT::Table->new('linuximage',-create=>1); }
 | |
|     		if ($linuximagetab) {
 | |
|     		    my %key_col = (imagename=>$imagename);
 | |
|     		    my %tb_cols=(pkglist=>$pkglistfile, 
 | |
| 				 pkgdir=>$ospkgdir,    				 
 | |
| 				 otherpkglist=>$otherpkgsfile,
 | |
|     				 otherpkgdir=>"$installroot/post/otherpkgs/$osver/$arch",
 | |
|     				 exlist=>$exlistfile,
 | |
|     				 postinstall=>$postfile,
 | |
|     				 rootimgdir=>"$installroot/netboot/$osver/$arch/$profile");
 | |
|     		    $linuximagetab->setAttribs(\%key_col, \%tb_cols);
 | |
|     		    
 | |
|     		} else {
 | |
|     		    return (1, "Cannot open the linuximage table.");
 | |
|     		}
 | |
|     	    }
 | |
|     	} else {
 | |
|     	    return (1, "Cannot open the osimage table."); 
 | |
|     	}
 | |
|         }  
 | |
|     }
 | |
|     if ($osimagetab) { $osimagetab->close(); }
 | |
|     if ($linuximagetab) { $linuximagetab->close(); }
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  get_mac_by_arp
 | |
|     Description:
 | |
|         Get the MAC address by arp protocol
 | |
| 
 | |
|     Arguments:
 | |
|         nodes: a reference to nodes array
 | |
|         display: whether just display the result, if not 'yes', the result will
 | |
|                  be written to the mac table.
 | |
|     Returns:
 | |
|         Return a hash with node name as key
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         xCAT::Utils->get_mac_by_arp($nodes, $display);
 | |
|     Comments:
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub get_mac_by_arp ()
 | |
| {
 | |
|     my ($class, $nodes, $display) = @_;
 | |
| 
 | |
|     my $node;
 | |
|     my $data;
 | |
|     my %ret = ();
 | |
|     my $unreachable_nodes = "";
 | |
|     my $noderange = join (',', @$nodes);
 | |
|     my @output = xCAT::Utils->runcmd("/opt/xcat/bin/pping $noderange", -1);
 | |
| 
 | |
|     foreach my $line (@output) {
 | |
|         my ($hostname, $result) = split ':', $line;
 | |
|         my ($token,    $status) = split ' ', $result;
 | |
|         chomp($token);
 | |
|         if ($token eq 'ping') {
 | |
|             $node->{$hostname}->{reachable} = 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     foreach my $n ( @$nodes ) {
 | |
|         if ( $node->{$n}->{reachable} ) {
 | |
|             my $output;
 | |
|             my $IP = xCAT::NetworkUtils::toIP( $n );
 | |
|             if ( xCAT::Utils->isAIX() ) {
 | |
|                 $output = `/usr/sbin/arp -a`;
 | |
|             } else {
 | |
|                 $output = `/sbin/arp -n`;
 | |
|             }
 | |
| 
 | |
|             my ($ip, $mac);
 | |
|             my @lines = split /\n/, $output;
 | |
|             foreach my $line ( @lines ) {
 | |
|                 if ( xCAT::Utils->isAIX() && $line =~ /\((\S+)\)\s+at\s+(\S+)/ ) {
 | |
|                     ($ip, $mac) = ($1,$2);
 | |
|                     ######################################################
 | |
|                     # Change mac format to be same as linux, but without ':'
 | |
|                     # For example: '0:d:60:f4:f8:22' to '000d60f4f822'
 | |
|                     ######################################################
 | |
|                     if ( $mac)
 | |
|                     {
 | |
|                         my @mac_sections = split /:/, $mac;
 | |
|                         for my $m (@mac_sections)
 | |
|                         {
 | |
|                             $m = "0$m" if ( length($m) == 1);
 | |
|                         }
 | |
|                         $mac = join '', @mac_sections;
 | |
|                     }
 | |
|                 } elsif ( $line =~ /^(\S+)+\s+\S+\s+(\S+)\s/ ) {
 | |
|                     ($ip, $mac) = ($1,$2);
 | |
|                 } else {
 | |
|                     ($ip, $mac) = (undef,undef);
 | |
|                 }
 | |
|                 if ( @$IP[1] !~ $ip ) {
 | |
|                     ($ip, $mac) = (undef,undef);
 | |
|                 } else {
 | |
|                     last;
 | |
|                 }
 | |
|             }
 | |
|             if ( $ip && $mac ) {
 | |
|                 if ( $display ne "yes" ) {
 | |
|                     #####################################
 | |
|                     # Write adapter mac to database
 | |
|                     #####################################
 | |
|                     my $mactab = xCAT::Table->new( "mac", -create=>1, -autocommit=>1 );
 | |
|                     $mactab->setNodeAttribs( $n,{mac=>$mac} );
 | |
|                     $mactab->close();
 | |
|                 }
 | |
|                 $ret{$n} = "MAC Address: $mac";
 | |
|             } else {
 | |
|                 $ret{$n} = "Cannot find MAC Address in arp table, please make sure target node and management node are in same network.";
 | |
|             }
 | |
|         } else {
 | |
|                 $ret{$n} = "Unreachable.";
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return \%ret;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  get_nodename_from_request
 | |
|     Description:
 | |
|         Determine whether _xcat_clienthost or _xcat_fqdn is the correct
 | |
|         nodename and return it.
 | |
| 
 | |
|     Arguments:
 | |
|         request: node request to look at
 | |
|     Returns:
 | |
|         The name of the node.
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         xCAT::Utils->get_nodenane_from_request($request);
 | |
|     Comments:
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub get_nodename_from_request()
 | |
| {
 | |
|     my $request = shift;
 | |
|     if($request->{node}){
 | |
|         return $request->{node};
 | |
|     }elsif($request->{'_xcat_clienthost'}){
 | |
|          my @nodenames = noderange($request->{'_xcat_clienthost'}->[0].",".$request->{'_xcat_clientfqdn'}->[0]);
 | |
|          return \@nodenames;
 | |
|     }
 | |
| 
 | |
|     return undef;
 | |
| }
 | |
| 
 | |
| # some directories will have xCAT database values, like:
 | |
| # $nodetype.os.  If that is the case we need to open up
 | |
| # the database and look at them.  We need to make sure
 | |
| # we do this sparingly...  We don't like tons of hits
 | |
| # to the database.
 | |
| sub subVars {
 | |
|   my $dir = shift;
 | |
|   if (($dir) && ($dir =~ /xCAT::SvrUtils/))
 | |
|   {
 | |
|     $dir = shift;
 | |
|   }
 | |
| 
 | |
|         my $node = shift;
 | |
|         my $type = shift;
 | |
|         my $callback = shift;
 | |
|         # parse all the dollar signs...
 | |
|         # if its a directory then it has a / in it, so you have to parse it.
 | |
|         # if its a server, it won't have one so don't worry about it.
 | |
|         my @arr = split("/", $dir);
 | |
|         my $fdir = "";
 | |
|         foreach my $p (@arr){
 | |
|                 # have to make this geric so $ can be in the midle of the name: asdf$foobar.sitadsf
 | |
|                 if($p =~ /\$/){
 | |
|                         my $pre;
 | |
|                         my $suf;
 | |
|                         my @fParts;
 | |
|                         if($p =~ /([^\$]*)([^# ]*)(.*)/){
 | |
|                                 $pre= $1;
 | |
|                                 $p = $2;
 | |
|                                 $suf = $3;
 | |
|                         }
 | |
|                         # have to sub here:
 | |
|                         # get rid of the $ sign.
 | |
|                         foreach my $part (split('\$',$p)){
 | |
|                                 if($part eq ''){ next; }
 | |
|                                 #$callback->({error=>["part is $part"],errorcode=>[1]});
 | |
|                                 # check if p is just the node name:
 | |
|                                 if($part eq 'node'){
 | |
|                                         # it is so, just return the node.
 | |
|                                         #$fdir .= "/$pre$node$suf";
 | |
|                                         push @fParts, $node;
 | |
|                                 }else{
 | |
|                                         # ask the xCAT DB what the attribute is.
 | |
|                                         my ($table, $col) = split('\.', $part);
 | |
|                                         unless($col){ $col = 'UNDEFINED' };
 | |
|                                         my $tab = xCAT::Table->new($table);
 | |
|                                         unless($tab){
 | |
|                                                 $callback->({error=>["$table does not exist"],errorcode=>[1]});
 | |
|                                                 return;
 | |
|                                         }
 | |
|                                         my $ent;
 | |
|                                         my $val;
 | |
|                                         if($table eq 'site'){
 | |
|                                                 #$val = $tab->getAttribs( { key => "$col" }, 'value' );
 | |
|                                                 #$val = $val->{'value'};
 | |
|                                                 my @vals = xCAT::TableUtils->get_site_attribute($col);
 | |
|                                                 $val = $vals[0];
 | |
|                                         }else{
 | |
|                                                 $ent = $tab->getNodeAttribs($node,[$col]);
 | |
|                                                 $val = $ent->{$col};
 | |
|                                         }
 | |
|                                         unless($val){
 | |
|                                                 # couldn't find the value!!
 | |
|                                                 $val = "UNDEFINED"
 | |
|                                         }
 | |
|                                         push @fParts, $val;
 | |
|                                 }
 | |
|                         }
 | |
|                         my $val = join('.', @fParts);
 | |
|                         if($type eq 'dir'){
 | |
|                                         $fdir .= "/$pre$val$suf";
 | |
|                         }else{
 | |
|                                         $fdir .= $pre . $val . $suf;
 | |
|                         }
 | |
|                 }else{
 | |
|                         # no substitution here
 | |
|                         $fdir .= "/$p";
 | |
|                 }
 | |
|         }
 | |
|         # now that we've processed variables, process commands
 | |
|         # this isn't quite rock solid.  You can't name directories with #'s in them.
 | |
|         if($fdir =~ /#CMD=/){
 | |
|                 my $dir;
 | |
|                 foreach my $p (split(/#/,$fdir)){
 | |
|                         if($p =~ /CMD=/){
 | |
|                                 $p =~ s/CMD=//;
 | |
|                                 my $cmd = $p;
 | |
|                                 #$callback->({info=>[$p]});
 | |
|                                 $p = `$p 2>&1`;
 | |
|                                 chomp($p);
 | |
|                                 #$callback->({info=>[$p]});
 | |
|                                 unless($p){
 | |
|                                         $p = "#CMD=$p did not return output#";
 | |
|                                 }
 | |
|                         }
 | |
|                         $dir .= $p;
 | |
|                 }
 | |
|                 $fdir = $dir;
 | |
|         }
 | |
| 
 | |
|         return $fdir;
 | |
| }
 | |
| 
 | |
| sub setupNFSTree {
 | |
|   my $node = shift;
 | |
|   if (($node) && ($node =~ /xCAT::SvrUtils/))
 | |
|   {
 | |
|     $node = shift;
 | |
|   }
 | |
| 
 | |
|     my $sip = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $cmd = "XCATBYPASS=Y litetree $node";
 | |
|     my @uris = xCAT::Utils->runcmd($cmd, 0);
 | |
| 
 | |
|     foreach my $uri (@uris) {
 | |
|         # parse the result
 | |
|         # the result looks like "nodename: nfsserver:directory";
 | |
|         $uri =~ m/\Q$node\E:\s+(.+):(.+)$/;
 | |
|         my $nfsserver = $1;
 | |
|         my $nfsdirectory = $2;
 | |
| 
 | |
|         if($nfsserver eq $sip) { # on the service node
 | |
| 
 | |
|             unless (-d $nfsdirectory) {
 | |
|                 if (-e $nfsdirectory) {
 | |
|                     unlink $nfsdirectory;
 | |
|                 }
 | |
|                 mkpath $nfsdirectory;
 | |
|             }
 | |
|         
 | |
|             $cmd = "showmount -e $nfsserver";
 | |
|             my @entries = xCAT::Utils->runcmd($cmd, 0);
 | |
|             shift @entries;
 | |
|             if(grep /\Q$nfsdirectory\E/, @entries) {
 | |
|                 $callback->({data=>["$nfsdirectory has been exported already!"]});
 | |
|                 # nothing to do
 | |
|             }else {
 | |
|                 $cmd = "/usr/sbin/exportfs :$nfsdirectory";
 | |
|                 xCAT::Utils->runcmd($cmd, 0);
 | |
|                 # exportfs can export this directory immediately
 | |
|                 $callback->({data=>["now $nfsdirectory is exported!"]});
 | |
|                 $cmd = "cat /etc/exports";
 | |
|                 @entries = xCAT::Utils->runcmd($cmd, 0);
 | |
|                 unless (my $entry = grep /\Q$nfsdirectory\E/, @entries) {
 | |
|                     #if there's no entry in /etc/exports, one with default options will be added
 | |
|                     $cmd = qq{echo "$nfsdirectory *(rw,no_root_squash,sync,no_subtree_check)" >> /etc/exports};
 | |
|                     xCAT::Utils->runcmd($cmd, 0);
 | |
|                     $callback->({data=>["$nfsdirectory is added to /etc/exports with default option"]});
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub setupStatemnt {
 | |
|     my $sip = shift;
 | |
|     if (($sip) && ($sip=~ /xCAT::SvrUtils/))
 | |
|     {
 | |
|       $sip = shift;
 | |
|     }
 | |
| 
 | |
|     my $statemnt = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     $statemnt =~ m/^(.+):(.+)$/;
 | |
|     my $nfsserver = $1;
 | |
|     my $nfsdirectory = $2;
 | |
|     if($sip eq xCAT::NetworkUtils->getipaddr($nfsserver)) {
 | |
|         unless (-d $nfsdirectory) {
 | |
|             if (-e $nfsdirectory) {
 | |
|                 unlink $nfsdirectory;
 | |
|             } 
 | |
|             mkpath $nfsdirectory;
 | |
|         }
 | |
| 
 | |
|         my $cmd = "showmount -e $nfsserver";
 | |
|         my @entries = xCAT::Utils->runcmd($cmd, 0);
 | |
|         shift @entries;
 | |
|         if(grep /\Q$nfsdirectory\E/, @entries) {
 | |
|             $callback->({data=>["$nfsdirectory has been exported already!"]});
 | |
|         } else {
 | |
|             $cmd = "/usr/sbin/exportfs :$nfsdirectory -o rw,no_root_squash,sync,no_subtree_check";
 | |
|             xCAT::Utils->runcmd($cmd, 0);
 | |
|             $callback->({data=>["now $nfsdirectory is exported!"]});
 | |
|             # add the directory into /etc/exports if not exist
 | |
|             $cmd = "cat /etc/exports";
 | |
|             @entries = xCAT::Utils->runcmd($cmd, 0);
 | |
|             if(my $entry = grep /\Q$nfsdirectory\E/, @entries) {
 | |
|                 unless ($entry =~ m/rw/) {
 | |
|                     $callback->({data=>["The $nfsdirectory should be with rw option in /etc/exports"]});
 | |
|                 }
 | |
|             }else {
 | |
|                 xCAT::Utils->runcmd(qq{echo "$nfsdirectory *(rw,no_root_squash,sync,no_subtree_check)" >>/etc/exports}, 0);
 | |
|                 $callback->({data => ["$nfsdirectory is added into /etc/exports with default options"]});
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------------------
 | |
| # Common method to send info back to the client
 | |
| # The last two args are optional, though $allerrornodes will unlikely be there without $node
 | |
| # TODO: investigate possibly removing this and using MsgUtils instead
 | |
| #
 | |
| #--------------------------------------------------------------------------------------------
 | |
| sub sendmsg {
 | |
|     my $text = shift;
 | |
|     my $callback = shift;
 | |
|     my $node = shift;
 | |
|     my %allerrornodes = shift;
 | |
|     my $descr;
 | |
|     my $rc;
 | |
|     if (ref $text eq 'HASH') {
 | |
|         die "not right now";
 | |
|     } elsif (ref $text eq 'ARRAY') {
 | |
|         $rc = $text->[0];
 | |
|         $text = $text->[1];
 | |
|     }
 | |
|     if ($text =~ /:/) {
 | |
|         ($descr,$text) = split /:/,$text,2;
 | |
|     }
 | |
|     $text =~ s/^ *//;
 | |
|     $text =~ s/ *$//;
 | |
|     my $msg;
 | |
|     my $curptr;
 | |
|     if ($node) {
 | |
|         $msg->{node}=[{name => [$node]}];
 | |
|         $curptr=$msg->{node}->[0];
 | |
|     } else {
 | |
|         $msg = {};
 | |
|         $curptr = $msg;
 | |
|     }
 | |
|     if ($rc) {
 | |
|         $curptr->{errorcode}=[$rc];
 | |
|         $curptr->{error}=[$text];
 | |
|         $curptr=$curptr->{error}->[0];
 | |
|         if (defined $node && %allerrornodes) {
 | |
|             $allerrornodes{$node}=1;
 | |
|         }
 | |
|     } else {
 | |
|         $curptr->{data}=[{contents=>[$text]}];
 | |
|         $curptr=$curptr->{data}->[0];
 | |
|         if ($descr) { $curptr->{desc}=[$descr]; }
 | |
|     }
 | |
| #        print $outfd freeze([$msg]);
 | |
| #        print $outfd "\nENDOFFREEZE6sK4ci\n";
 | |
| #        yield;
 | |
| #        waitforack($outfd);
 | |
|     $callback->($msg);
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| =head3  build_deps
 | |
|     Look up the "deps" table to generate the dependencies for the nodes
 | |
|     Arguments:
 | |
|         nodes: The nodes list in an array reference
 | |
|     Returns:
 | |
|         depset: dependencies hash reference 
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         my $deps = xCAT::SvrUtils->build_deps($req->{node});
 | |
|     Comments:
 | |
|         none
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub build_deps()
 | |
| {
 | |
|     my ($class, $nodes, $cmd) = @_;
 | |
|     my %depshash = ();
 | |
| 
 | |
|     my $depstab  = xCAT::Table->new('deps');
 | |
|     if (!defined($depstab)) {
 | |
|         return undef;
 | |
|     }
 | |
| 
 | |
|     my $depset = $depstab->getNodesAttribs($nodes,[qw(nodedep msdelay cmd)]);
 | |
|     if (!defined($depset))
 | |
|     {
 | |
|         return undef;
 | |
|     }
 | |
|     foreach my $node (@$nodes) {
 | |
|         # Delete the nodes without dependencies from the hash
 | |
|         if (!defined($depset->{$node}[0])) {
 | |
|             delete($depset->{$node});
 | |
|         } 
 | |
|     }
 | |
| 
 | |
|     # the deps hash does not check the 'cmd',
 | |
|     # use the realdeps to reflect the 'cmd' also
 | |
|     my $realdep;
 | |
|     foreach my $node (@$nodes) {
 | |
|             foreach my $depent (@{$depset->{$node}}){
 | |
|                 my @depcmd = split(/,/, $depent->{'cmd'});
 | |
|                 #dependency match
 | |
|                 if (grep(/^$cmd$/, @depcmd)) {
 | |
|                     #expand the noderange
 | |
|                     my @nodedep = xCAT::NodeRange::noderange($depent->{'nodedep'},1);
 | |
|                     my $depsnode = join(',', @nodedep);
 | |
|                     if ($depsnode) {
 | |
|                         $depent->{'nodedep'} = $depsnode;
 | |
|                         push @{$realdep->{$node}}, $depent;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     return $realdep;
 | |
| }
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  handle_deps
 | |
|     Group the nodes according to the deps hash returned from build_deps
 | |
|     Arguments:
 | |
|         deps: the dependencies hash reference
 | |
|         nodes: The nodes list in an array reference
 | |
|         $callback: sub request callback
 | |
|     Returns:
 | |
|         nodeseq: the nodes categorized based on dependencies
 | |
|                  returns 1 if runs into problem
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         my $deps = xCAT::SvrUtils->handle_deps($deps, $req->{node});
 | |
|     Comments:
 | |
|         none
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub handle_deps()
 | |
| {
 | |
|     my ($class, $dephash, $nodes, $callback) = @_;
 | |
| 
 | |
|     # a small subroutine to remove some specific node from a comma separated list
 | |
|     sub remove_node_from_list()
 | |
|     {
 | |
|         my ($string, $nodetoremove) = @_;
 | |
|         my @arr = split(',', $string);
 | |
|         my @newarr = ();
 | |
|         foreach my $tmp (@arr) {
 | |
|             if ($tmp ne $nodetoremove) {
 | |
|                 push @newarr, $tmp;
 | |
|             }
 | |
|         }
 | |
|         return join(',', @newarr);
 | |
|     }
 | |
| 
 | |
|     # This is an example of the deps hash ref
 | |
|     #  DB<3> x $deps
 | |
|     #0  HASH(0x239db47c)
 | |
|     #   'aixcn1' => ARRAY(0x23a26be0)
 | |
|     #      0  HASH(0x23a21968) 
 | |
|     #         'cmd' => 'off' 
 | |
|     #         'msdelay' => 10000 
 | |
|     #         'node' => 'aixcn1' 
 | |
|     #         'nodedep' => 'aixmn2' 
 | |
|     #   'aixsn1' => ARRAY(0x23a2219c)
 | |
|     #      0  HASH(0x23a21728) 
 | |
|     #         'cmd' => 'off' 
 | |
|     #         'msdelay' => 10000 
 | |
|     #         'node' => 'aixsn1' 
 | |
|     #         'nodedep' => 'aixcn1' 
 | |
| 
 | |
|     #copy the dephash, do not manipulate the subroutine argument $dephash
 | |
|     my $deps;
 | |
|     foreach my $node (keys %{$dephash}) {
 | |
|         my $i = 0;
 | |
|         for ($i = 0; $i < scalar(@{$dephash->{$node}}); $i++) {
 | |
|             foreach my $attr (keys %{$dephash->{$node}->[$i]}) {
 | |
|                 $deps->{$node}->[$i]->{$attr} = $dephash->{$node}->[$i]->{$attr};
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #needs to search the nodes list a lot of times
 | |
|     #using hash will be more effective
 | |
|     my %nodelist;
 | |
|     foreach my $node (@{$nodes}) {
 | |
|         $nodelist{$node} = 1;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     # check if any depnode is not in the nodelist,
 | |
|     # print warning message
 | |
|     my $depsnotinargs;
 | |
|     foreach my $node (keys %{$deps}){
 | |
|         my $keepnode = 0;
 | |
|         foreach my $depent (@{$deps->{$node}}){
 | |
|             # an autonomy dependency group?
 | |
|             foreach my $dep (split(/,/, $depent->{'nodedep'})) {
 | |
|                 if (!defined($nodelist{$dep})) {
 | |
|                    $depsnotinargs->{$dep} = 1; 
 | |
|                    $depent->{'nodedep'} = &remove_node_from_list($depent->{'nodedep'}, $dep);
 | |
|                 }       
 | |
|             }       
 | |
|             if ($depent->{'nodedep'}) {
 | |
|                 $keepnode = 1;
 | |
|             }
 | |
|         }
 | |
|         if (!$keepnode) {
 | |
|             delete($deps->{$node});
 | |
|         }
 | |
|     }
 | |
|     if (scalar(keys %{$depsnotinargs}) > 0) {
 | |
|         my $n = join(',', keys %{$depsnotinargs});
 | |
|   
 | |
|         my %output;
 | |
|         $output{data} = ["The following nodes are dependencies for some nodes passed in through arguments, but not in the command arguments: $n, make sure these nodes are in correct state"]; 
 | |
|         $callback->( \%output );
 | |
|     }                                                            
 | |
|                                                                              
 | |
| 
 | |
| 
 | |
|     my $arrayindex = 0;                                                      
 | |
|     my $nodeseq;                                                             
 | |
|     #handle all the nodes
 | |
|     while (keys %nodelist) {                                                 
 | |
| 
 | |
|        my @curnodes;
 | |
|        foreach my $node (keys %nodelist) {                                  
 | |
|             #no dependency                                                  
 | |
|            if (!defined($deps->{$node})) {                                  
 | |
|                $nodeseq->[$arrayindex]->{$node} = 1;                        
 | |
|                delete($nodelist{$node});                                    
 | |
|                push @curnodes, $node;
 | |
|            }                                                                
 | |
|        }                                                                    
 | |
|                                                                              
 | |
|        if (scalar(@curnodes) == 0) {
 | |
|            # no nodes in this loop at all,
 | |
|            # means infinite loop???
 | |
|            my %output;
 | |
|            my $nodesinlist = join(',', keys %nodelist);
 | |
|            $output{errorcode}=1;
 | |
|            $output{data} = ["Loop dependency, check your deps table, may be related to the following nodes: $nodesinlist"];
 | |
|            $callback->( \%output );
 | |
|            return 1;
 | |
|        }
 | |
| 
 | |
|        # update deps for the next loop                              
 | |
|        # remove the node from the 'nodedep' attribute               
 | |
|        my $keepnode = 0;                                            
 | |
|        foreach my $nodeindeps (keys %{$deps}) {
 | |
|            my $keepnode = 0;
 | |
|            foreach my $depent (@{$deps->{$nodeindeps}}){                      
 | |
|                  #remove the curnodes from the 'nodedep'
 | |
|                  foreach my $nodetoremove (@curnodes) {
 | |
|                      $depent->{'nodedep'} = &remove_node_from_list($depent->{'nodedep'}, $nodetoremove);
 | |
|                  }
 | |
|                  if ($depent->{'nodedep'}) {
 | |
|                      $keepnode = 1;
 | |
|                  }
 | |
|             }
 | |
|             if (!$keepnode) {
 | |
|                 delete($deps->{$nodeindeps});
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         # the round is over, jump to the next arrary entry
 | |
|         $arrayindex++;  
 | |
|     }                                                                  
 | |
|     return $nodeseq; 
 | |
| }
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   parseosver 
 | |
|     parse osver to osdistribution base name,majorversion,minorversion
 | |
|     Returns:
 | |
|        list (osdistribution base name, majorversion,minorversion)
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Input:
 | |
|         osver
 | |
|     Example:
 | |
|     ($basename,$majorversion,$minorversion)=xCAT::Utils->parseosver($osver);
 | |
|     Comments:
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub parseosver
 | |
| {
 | |
|   my $osver=shift;
 | |
| 
 | |
|   if($osver =~ (/(\D+)(\d*)\.*(\d*)/))
 | |
|   {
 | |
|         return ($1,$2,$3);
 | |
|   }
 | |
| 
 | |
|   return ();
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3 update_osdistro_table
 | |
|        This function is called after copycds. It will update the osdistro table with
 | |
|        given osver and arch 
 | |
|     Arguments:
 | |
|         osver
 | |
|         arch
 | |
|         ospkgdir
 | |
|     Returns:
 | |
|         an array (retcode, errmsg). The first one is the return code. If 0, it means succesful. 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| sub update_osdistro_table
 | |
| { 
 | |
|     my $osver = shift;  #like sle11, rhel5.3 
 | |
|     if (($osver) && ($osver =~ /xCAT::SvrUtils/)) {
 | |
|         $osver = shift;
 | |
|     }
 | |
|     my $arch = shift;  #like ppc64, x86, x86_64
 | |
|     my $path=shift;
 | |
|     my $distname=shift;
 | |
|  
 | |
|     my $basename=undef;
 | |
|     my $majorversion=undef;
 | |
|     my $minorversion=undef;
 | |
| 	
 | |
|     my %keyhash=();
 | |
|     my %updates=();
 | |
| 
 | |
|     my $ostype="Linux";  #like Linux, Windows
 | |
|     if (($osver =~ /^win/) || ($osver =~ /^imagex/)) {
 | |
| 	if ($osver =~ /^win\d/) {
 | |
| 		$osver =~ s/^win/windows/;
 | |
| 	} elsif ($osver =~ /^imagex/) {
 | |
|         	$osver="windows";
 | |
| 	}
 | |
|         $ostype="Windows";
 | |
|     }
 | |
|     if ($osver =~ /hyperv/) {
 | |
| 	$ostype = "Windows";
 | |
|     }
 | |
| 
 | |
| 
 | |
|    unless($distname){
 | |
| 	$distname=$osver."-".$arch;
 | |
|    }
 | |
|      
 | |
|     $keyhash{osdistroname}    = $distname;
 | |
| 
 | |
|     $updates{type}=$ostype;
 | |
|     if($arch){
 | |
|              $updates{arch}    = $arch;
 | |
|     }
 | |
| #split $osver to basename,majorversion,minorversion 
 | |
|     if($osver){
 | |
|               ($updates{basename},$updates{majorversion},$updates{minorversion}) = &parseosver($osver);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     my $tab = xCAT::Table->new('osdistro',-create=>1);
 | |
| 
 | |
|     unless($tab)
 | |
|     {
 | |
|           return(1,"failed to open table 'osdistro'!");
 | |
|     }
 | |
| 
 | |
|     if($path)
 | |
|         {
 | |
|               $path =~ s/\/+$//;
 | |
|               (my $ref) = $tab->getAttribs(\%keyhash, 'dirpaths');
 | |
|               if ($ref and $ref->{dirpaths} )
 | |
|                {
 | |
| #if $path does not exits in "dirpaths" of osdistro,append the $path delimited with a ",";otherwise keep the original value
 | |
|                     unless($ref->{dirpaths} =~ /^($path)\/*,|,($path)\/*,|,($path)\/*$|^($path)\/*$/)
 | |
|                     {
 | |
|                            $updates{dirpaths}=$ref->{dirpaths}.','.$path;
 | |
|                     }
 | |
|                 }else
 | |
|                 {
 | |
|                         $updates{dirpaths}   = $path;
 | |
|                 }
 | |
|         }
 | |
| 
 | |
| 
 | |
|         if(%updates)
 | |
|         {
 | |
|                 $tab->setAttribs( \%keyhash,\%updates );
 | |
|                 $tab->commit;
 | |
|         }
 | |
|         $tab->close;
 | |
| 
 | |
|         return(0,"osdistro $distname update success");
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| =head3 getpostbootscripts
 | |
|     Get the  the postbootscript list for the Linux nodes as defined in
 | |
|     the osimage table postbootscripts attribute 
 | |
| 
 | |
|     Arguments:
 | |
|       $nodes - array of nodes
 | |
|     Returns:
 | |
|       reference of a hash of node=>postbootscripts comma separated list
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|     Example:
 | |
|          my $node_postbootscripts=xCAT::SvrUtils->getpostbootscripts($nodes);
 | |
|     Comments:
 | |
|         none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| sub getpostbootscripts()
 | |
| {
 | |
|   my $nodes = shift;
 | |
|   if (($nodes) && ($nodes =~ /xCAT::SvrUtils/))
 | |
|   {
 | |
|     $nodes = shift;
 | |
|   }
 | |
|   my %node_postbootscript = ();
 | |
|   my %osimage_postbootscript = ();
 | |
| 
 | |
| 
 | |
| 
 | |
| 	# get the profile attributes for the nodes
 | |
| 	my $nodetype_t = xCAT::Table->new('nodetype');
 | |
| 	unless ($nodetype_t) {
 | |
| 	    return ;
 | |
|    }
 | |
| 	my $nodetype_v = $nodetype_t->getNodesAttribs($nodes, ['provmethod']);
 | |
|    my @osimages;	
 | |
|    my $osimage_t = xCAT::Table->new('osimage');
 | |
|    unless ($osimage_t) {
 | |
|       return ;
 | |
|    }
 | |
| 	foreach my $node (@$nodes) {
 | |
| 	    my $provmethod=$nodetype_v->{$node}->[0]->{'provmethod'};
 | |
| 	    if (($provmethod) && ( $provmethod ne "install") && ($provmethod ne "netboot") && ($provmethod ne "statelite")) {
 | |
|        # then get the postbootscripts from the osimage
 | |
|           my $postbootscripts = $osimage_t->getAttribs({imagename=>$provmethod}, 'postbootscripts');
 | |
|           if ($postbootscripts && $postbootscripts->{'postbootscripts'}) {
 | |
|            $node_postbootscript{$node} = $postbootscripts->{'postbootscripts'};
 | |
|           }
 | |
|         }
 | |
| 
 | |
| 	    
 | |
|    }
 | |
|    return \%node_postbootscript;
 | |
|   }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   getplatform
 | |
|        Translate the os to platform name.
 | |
|        Use this subroutine to replace the getplatform subroutines in different plugins.
 | |
|     Arguments:
 | |
|         os: like rhels6.3 or sles11.2
 | |
|     Returns:
 | |
|         platform: like rh and sles
 | |
|     Example:
 | |
|          my $platform = xCAT::SvrUtils->getplatform($os);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| sub getplatform {
 | |
|     my $os = shift;  #like sles11.1, rhels6.3
 | |
|     if (($os) && ($os =~ /xCAT::SvrUtils/)) {
 | |
|         $os = shift;
 | |
|     }
 | |
| 
 | |
|     my $platform;
 | |
|     if ($os =~ /rh.*/) 
 | |
|     {
 | |
| 	$platform = "rh";
 | |
|     }
 | |
|     elsif ($os =~ /sles.*/) 
 | |
|     {
 | |
| 	$platform = "sles";
 | |
|     }
 | |
|     elsif ($os =~ /suse.*/) 
 | |
|     {
 | |
| 	$platform = "suse";
 | |
|     }
 | |
|     elsif ($os =~ /centos.*/)
 | |
|     {
 | |
| 	$platform = "centos";
 | |
|     }
 | |
|     elsif ($os =~ /fedora.*/)
 | |
|     {
 | |
| 	$platform = "fedora";
 | |
|     }
 | |
|     elsif ($os =~ /esxi.*/)
 | |
|     {
 | |
| 	$platform = "esxi";
 | |
|     }
 | |
|     elsif ($os =~ /esx.*/)
 | |
|     {
 | |
| 	$platform = "esx";
 | |
|     }
 | |
|     elsif ($os =~ /SL.*/)
 | |
|     {
 | |
|         $platform = "SL";
 | |
|     }
 | |
|     elsif ($os =~ /ol.*/)
 | |
|     {
 | |
|         $platform = "ol";
 | |
|     }
 | |
|     elsif ($os =~ /debian.*/) {
 | |
|         $platform = "debian";
 | |
|     }
 | |
|     elsif ($os =~ /ubuntu.*/){
 | |
|         $platform = "ubuntu";
 | |
|     }
 | |
|     elsif ($os =~ /AIX.*/)
 | |
|     {
 | |
|         $platform = "AIX";
 | |
|     }
 | |
|     elsif ($os =~ /win.*/)
 | |
|     {
 | |
|         $platform = "windows";
 | |
|     }
 | |
| 
 | |
|     return $platform;
 | |
| }
 | |
| 1;
 |