git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@15575 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			1667 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1667 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| #!/usr/bin/env perl
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| package xCAT::TableUtils;
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| 
 | |
| # if AIX - make sure we include perl 5.8.2 in INC path.
 | |
| #       Needed to find perl dependencies shipped in deps tarball.
 | |
| if ($^O =~ /^aix/i) {
 | |
|         use lib "/usr/opt/perl5/lib/5.8.2/aix-thread-multi";
 | |
|         use lib "/usr/opt/perl5/lib/5.8.2";
 | |
|         use lib "/usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi";
 | |
|         use lib "/usr/opt/perl5/lib/site_perl/5.8.2";
 | |
| }
 | |
| 
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| use strict;
 | |
| require xCAT::Table;
 | |
| use File::Path;
 | |
| #-----------------------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|  list_all_nodes
 | |
| 
 | |
| 	Arguments:
 | |
| 
 | |
| 	Returns:
 | |
| 	    an array of all define nodes from the nodelist table
 | |
| 	Globals:
 | |
| 		none
 | |
| 	Error:
 | |
| 		undef
 | |
| 	Example:
 | |
| 	   @nodes=xCAT::TableUtils->list_all_nodes;
 | |
| 	Comments:
 | |
| 		none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #------------------------------------------------------------------------
 | |
| sub list_all_nodes
 | |
| {
 | |
|     my @nodes;
 | |
|     my @nodelist;
 | |
|     my $nodelisttab;
 | |
|     if ($nodelisttab = xCAT::Table->new("nodelist"))
 | |
|     {
 | |
|         my @attribs = ("node");
 | |
|         @nodes = $nodelisttab->getAllAttribs(@attribs);
 | |
|         foreach my $node (@nodes)
 | |
|         {
 | |
|             push @nodelist, $node->{node};
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         xCAT::MsgUtils->message("E", " Could not read the nodelist table\n");
 | |
|     }
 | |
|     return @nodelist;
 | |
| }
 | |
| 
 | |
| #-----------------------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|  list_all_nodegroups
 | |
| 
 | |
| 	Arguments:
 | |
| 
 | |
| 	Returns:
 | |
| 	    an array of all define node groups from the nodelist and nodegroup
 | |
|             table
 | |
| 	Globals:
 | |
| 		none
 | |
| 	Error:
 | |
| 		undef
 | |
| 	Example:
 | |
| 	   @nodegrps=xCAT::TableUtils->list_all_nodegroups;
 | |
| 	Comments:
 | |
| 		none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #------------------------------------------------------------------------
 | |
| sub list_all_node_groups
 | |
| {
 | |
|     my @grouplist;
 | |
|     my @grouplist2;
 | |
|     my @distinctgroups;
 | |
|     my $nodelisttab;
 | |
|     if ($nodelisttab = xCAT::Table->new("nodelist"))
 | |
|     {
 | |
|         my @attribs = ("groups");
 | |
|         @grouplist = $nodelisttab->getAllAttribs(@attribs);
 | |
| 
 | |
|         # build a distinct list of unique group names
 | |
|         foreach my $group (@grouplist)
 | |
|         {
 | |
|             my $gnames = $group->{groups};
 | |
|             my @groupnames = split ",", $gnames;
 | |
|             foreach my $groupname (@groupnames)
 | |
|             {
 | |
|                 if (!grep(/^$groupname$/, @distinctgroups))
 | |
|                 {    # not already in list
 | |
|                     push @distinctgroups, $groupname;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         xCAT::MsgUtils->message("E", " Could not read the nodelist table\n");
 | |
|     }
 | |
|     $nodelisttab->close;
 | |
|     # now read the nodegroup table
 | |
|     if ($nodelisttab = xCAT::Table->new("nodegroup"))
 | |
|      {
 | |
|          my @attribs = ("groupname");
 | |
|          @grouplist = $nodelisttab->getAllAttribs(@attribs);
 | |
|  
 | |
|          # build a distinct list of unique group names
 | |
|          foreach my $group (@grouplist)
 | |
|          {
 | |
|              my $groupname = $group->{groupname};
 | |
|              if (!grep(/^$groupname$/, @distinctgroups))
 | |
|              {    # not already in list
 | |
|                  push @distinctgroups, $groupname;
 | |
|              }
 | |
|          }
 | |
|          $nodelisttab->close;
 | |
|      }
 | |
|      else
 | |
|      {
 | |
|          xCAT::MsgUtils->message("E", " Could not read the nodegroup table\n");
 | |
|      }
 | |
| 
 | |
|     return @distinctgroups;
 | |
| }
 | |
| #-------------------------------------------------------------------------------- 	 
 | |
| 	  	 
 | |
| =head3   bldnonrootSSHFiles 	 
 | |
| 	  	 
 | |
| 	            Builds authorized_keyfiles for the non-root id 	 
 | |
| 	            It must not only contain the public keys for the non-root id 	 
 | |
| 	                    but also the public keys for root 	 
 | |
| 	  	 
 | |
| 	         Arguments: 	 
 | |
| 	               from_userid -current id running xdsh from the command line 	 
 | |
| 	         Returns: 	 
 | |
| 	  	 
 | |
| 	         Globals: 	 
 | |
| 	               $::CALLBACK 	 
 | |
| 	         Error: 	 
 | |
| 	  	 
 | |
| 	         Example: 	 
 | |
| 	                 xCAT::TableUtils->bldnonrootSSHFiles; 	 
 | |
| 	  	 
 | |
| 	         Comments: 	 
 | |
| 	                 none 	 
 | |
| 	  	 
 | |
| =cut 	 
 | |
| 	  	 
 | |
| #-------------------------------------------------------------------------------- 	 
 | |
| 	  	 
 | |
| sub bldnonrootSSHFiles 	 
 | |
| { 	 
 | |
|     my ($class, $from_userid) = @_; 	 
 | |
|     my ($cmd, $rc); 	 
 | |
|     my $rsp = {}; 	 
 | |
|     if ($::VERBOSE) 	 
 | |
|     { 	 
 | |
|         $rsp->{data}->[0] = "Building  SSH Keys for $from_userid"; 	 
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); 	 
 | |
|     } 	 
 | |
|     my $home     = xCAT::Utils->getHomeDir($from_userid); 	 
 | |
|     # Handle non-root userid may not be in /etc/passwd maybe LDAP 	 
 | |
|     if (!$home) { 	 
 | |
|         $home=`su - $from_userid -c pwd`; 	 
 | |
|         chop $home; 	 
 | |
|     } 	 
 | |
|     my $roothome = xCAT::Utils->getHomeDir("root"); 	 
 | |
|     if (xCAT::Utils->isMN()) {    # if on Management Node 	 
 | |
|         if (!(-e "$home/.ssh/id_rsa.pub")) 	 
 | |
|         { 	 
 | |
|             return 1; 	 
 | |
|         } 	 
 | |
|     } 	 
 | |
|     # make tmp directory to hold authorized_keys for node transfer 	 
 | |
|     if (!(-e "$home/.ssh/tmp")) { 	 
 | |
|         $cmd = " mkdir $home/.ssh/tmp"; 	 
 | |
|         xCAT::Utils->runcmd($cmd, 0); 	 
 | |
|         $rsp = {}; 	 
 | |
|         if ($::RUNCMD_RC != 0) 	 
 | |
|         { 	 
 | |
|             $rsp->{data}->[0] = "$cmd failed.\n"; 	 
 | |
|             xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); 	 
 | |
|             return (1); 	 
 | |
| 
 | |
|         } 	 
 | |
|     } 	 
 | |
|     # create authorized_key file in tmp directory for transfer 	 
 | |
|     if (xCAT::Utils->isMN()) {    # if on Management Node 	 
 | |
|         $cmd = " cp $home/.ssh/id_rsa.pub $home/.ssh/tmp/authorized_keys"; 	 
 | |
|     } else {  # SN 	 
 | |
|         $cmd = " cp $home/.ssh/authorized_keys $home/.ssh/tmp/authorized_keys"; 	 
 | |
|     } 	 
 | |
|     xCAT::Utils->runcmd($cmd, 0); 	 
 | |
|     $rsp = {}; 	 
 | |
|     if ($::RUNCMD_RC != 0) 	 
 | |
|     { 	 
 | |
|         $rsp->{data}->[0] = "$cmd failed.\n"; 	 
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); 	 
 | |
|         return (1); 	 
 | |
| 
 | |
|     } 	 
 | |
|     else 	 
 | |
|     { 	 
 | |
|         chmod 0600, "$home/.ssh/tmp/authorized_keys"; 	 
 | |
|         if ($::VERBOSE) 	 
 | |
|         { 	 
 | |
|             $rsp->{data}->[0] = "$cmd succeeded.\n"; 	 
 | |
|             xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); 	 
 | |
|         } 	 
 | |
|     } 	 
 | |
|     if (xCAT::Utils->isMN()) {    # if on Management Node 	 
 | |
|         # if cannot access, warn and continue 	 
 | |
|         $rsp = {}; 	 
 | |
|         $cmd = "cat $roothome/.ssh/id_rsa.pub >> $home/.ssh/tmp/authorized_keys"; 	 
 | |
|         xCAT::Utils->runcmd($cmd, 0); 	 
 | |
|         if ($::RUNCMD_RC != 0) 	 
 | |
|         { 	 
 | |
|             $rsp->{data}->[0] = "Warning: Cannot give $from_userid root ssh authority. \n"; 	 
 | |
|             xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); 	 
 | |
| 
 | |
|         } 	 
 | |
|         else 	 
 | |
|         { 	 
 | |
|             if ($::VERBOSE) 	 
 | |
|             { 	 
 | |
|                 $rsp->{data}->[0] = "$cmd succeeded.\n"; 	 
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $::CALLBACK); 	 
 | |
|             } 	 
 | |
|         } 	 
 | |
|     } 	 
 | |
| 
 | |
| 
 | |
|     return (0); 	 
 | |
| }
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   setupSSH
 | |
| 
 | |
|         Generates if needed and Transfers the ssh keys 
 | |
| 		fOr a userid to setup ssh to the input nodes.
 | |
| 
 | |
|         Arguments:
 | |
|                Array of nodes
 | |
|         Returns:
 | |
| 
 | |
|         Env Variables: $DSH_FROM_USERID,  $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
 | |
|           the ssh keys are transferred from the $DSH_FROM_USERID to the $DSH_TO_USERID
 | |
|           on the node(s).  The DSH_REMOTE_PASSWORD and the DSH_FROM_USERID 
 | |
|                must be obtained by
 | |
| 		         the calling script or from the xdsh client
 | |
| 
 | |
|         Globals:
 | |
|               $::XCATROOT  ,  $::CALLBACK
 | |
|         Error:
 | |
|              0=good,  1=error
 | |
|         Example:
 | |
|                 xCAT::TableUtils->setupSSH(@target_nodes);
 | |
|         Comments:
 | |
| 			Does not setup known_hosts.  Assumes automatically
 | |
| 			setup by SSH  ( ssh config option StrictHostKeyChecking no should
 | |
| 			   be set in the ssh config file).
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub setupSSH
 | |
| {
 | |
|     my ($class, $ref_nodes) = @_;
 | |
|     my @nodes    = $ref_nodes;
 | |
|     my @badnodes = ();
 | |
|     my $n_str    = $nodes[0];
 | |
|     my $SSHdir   = xCAT::TableUtils->getInstallDir() . "/postscripts/_ssh";
 | |
|     if (!($ENV{'DSH_REMOTE_PASSWORD'}))
 | |
|     {
 | |
|         my $rsp = ();
 | |
|         $rsp->{data}->[0] =
 | |
|           "User password for the ssh key exchange has not been input. xdsh -K cannot complete.\n";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|         return;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     # setup who the keys are coming from and who they are going to
 | |
|     my $from_userid;
 | |
|     my $to_userid;
 | |
|     if (!($ENV{'DSH_FROM_USERID'}))
 | |
|     {
 | |
|         my $rsp = ();
 | |
|         $rsp->{data}->[0] =
 | |
|           "DSH From Userid  has not been input. xdsh -K cannot complete.\n";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|         return;
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $from_userid = $ENV{'DSH_FROM_USERID'};
 | |
|     }
 | |
|     if (!($ENV{'DSH_TO_USERID'}))
 | |
|     {
 | |
|         my $rsp = ();
 | |
|         $rsp->{data}->[0] =
 | |
|           "DSH to Userid  has not been input. xdsh -K cannot complete.\n";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|         return;
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $to_userid = $ENV{'DSH_TO_USERID'};
 | |
|     }
 | |
| 
 | |
| 
 | |
|     #
 | |
|     # if we are running as root
 | |
|     # for non-root users, keys were generated in the xdsh client code
 | |
|     #
 | |
| 
 | |
|     $::REMOTE_SHELL = "/usr/bin/ssh";
 | |
|     my $rsp = {};
 | |
| 
 | |
|     # Get the home directory
 | |
|     my $home = xCAT::Utils->getHomeDir($from_userid);
 | |
|     $ENV{'DSH_FROM_USERID_HOME'} = $home;
 | |
| 
 | |
|     if ($from_userid eq "root")
 | |
|     {
 | |
| 
 | |
|         # make the directory to hold keys to transfer to the nodes
 | |
|         if (!-d $SSHdir)
 | |
|         {
 | |
|             mkpath("$SSHdir", { mode => 0755 });
 | |
|         }
 | |
| 
 | |
|         # generates new keys for root, if they do not already exist
 | |
|         my $rc=
 | |
|      xCAT::RemoteShellExp->remoteshellexp("k",$::CALLBACK,$::REMOTE_SHELL);
 | |
|        if ($rc != 0) {
 | |
|             $rsp->{data}->[0] = "remoteshellexp failed generating keys.";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|        }
 | |
|     }
 | |
|     
 | |
|     # build the shell copy script, needed Perl not always there
 | |
|     # for root and non-root ids
 | |
|     open(FILE, ">$home/.ssh/copy.sh")
 | |
|       or die "cannot open file $home/.ssh/copy.sh\n";
 | |
|     print FILE "#!/bin/sh
 | |
| umask 0077
 | |
| home=`egrep \"^$to_userid:\" /etc/passwd | cut -f6 -d :`
 | |
| if [ $home ]; then
 | |
|   dest_dir=\"\$home/.ssh\"
 | |
| else
 | |
|   home=`su - root -c pwd`
 | |
|   dest_dir=\"\$home/.ssh\"
 | |
| fi
 | |
| mkdir -p \$dest_dir
 | |
| cat /tmp/$to_userid/.ssh/authorized_keys >> \$home/.ssh/authorized_keys 2>&1
 | |
| cp /tmp/$to_userid/.ssh/id_rsa  \$home/.ssh/id_rsa 2>&1
 | |
| chmod 0600 \$home/.ssh/id_* 2>&1
 | |
| rm -f /tmp/$to_userid/.ssh/* 2>&1
 | |
| rmdir \"/tmp/$to_userid/.ssh\"
 | |
| rmdir \"/tmp/$to_userid\" \n";
 | |
| 
 | |
|     close FILE;
 | |
|     chmod 0777,"$home/.ssh/copy.sh";
 | |
|     my $auth_key=0;
 | |
|     my $auth_key2=0;
 | |
|     if ($from_userid eq "root")
 | |
|     {
 | |
|        my $rc = xCAT::TableUtils->cpSSHFiles($SSHdir);
 | |
|        if ($rc != 0)
 | |
|        {    # error
 | |
|                 $rsp->{data}->[0] = "Error running cpSSHFiles.\n";
 | |
|                 xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|                 return 1;
 | |
| 
 | |
|        }
 | |
|        if (xCAT::Utils->isMN()) {    # if on Management Node
 | |
|             # copy the copy install file to the install directory, if from and
 | |
|             # to userid are root
 | |
|             if ($to_userid eq "root")
 | |
|             {
 | |
| 
 | |
|                 my $cmd = " cp $home/.ssh/copy.sh $SSHdir/copy.sh";
 | |
|                 xCAT::Utils->runcmd($cmd, 0);
 | |
|                 my $rsp = {};
 | |
|                 if ($::RUNCMD_RC != 0)
 | |
|                 {
 | |
|                     $rsp->{data}->[0] = "$cmd failed.\n";
 | |
|                     xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|                     return (1);
 | |
| 
 | |
|                 }
 | |
|             }
 | |
|         }  # end is MN
 | |
|     }
 | |
|     else {    # from_userid is not root
 | |
|                 # build the authorized key files for non-root user
 | |
|             xCAT::TableUtils->bldnonrootSSHFiles($from_userid);
 | |
|     }
 | |
| 
 | |
|     # send the keys to the nodes   for root or some other id
 | |
|     #
 | |
|     # This environment variable determines whether to setup 
 | |
|     # node to node ssh
 | |
|     # The nodes must be checked against the site.sshbetweennodes attribute
 | |
|     # For root user and not to devices only to nodes 
 | |
|     if (($from_userid eq "root") && (!($ENV{'DEVICETYPE'}))) {
 | |
|       my $enablenodes;
 | |
|       my $disablenodes;
 | |
|       my @nodelist=  split(",", $n_str);
 | |
|       foreach my $n (@nodelist)
 | |
|       {
 | |
|          my $enablessh=xCAT::TableUtils->enablessh($n);
 | |
|          if ($enablessh == 1) {
 | |
|            $enablenodes .= $n;
 | |
|            $enablenodes .= ","; 
 | |
|          } else {
 | |
|            $disablenodes .= $n;
 | |
|            $disablenodes .= ","; 
 | |
|          }
 | |
| 
 | |
|       }
 | |
|       my $cmd;
 | |
|       if ($enablenodes) {  # node on list to setup nodetonodessh
 | |
|          chop $enablenodes;  # remove last comma
 | |
|          $ENV{'DSH_ENABLE_SSH'} = "YES";
 | |
|          my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes);
 | |
|          if ($rc != 0)
 | |
|          {
 | |
|           $rsp->{data}->[0] = "remoteshellexp failed sending keys to enablenodes.";
 | |
|           xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
| 
 | |
|           }
 | |
|       }
 | |
|       if ($disablenodes) {  # node on list to setup nodetonodessh
 | |
|          chop $disablenodes;  # remove last comma
 | |
|          my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes);
 | |
|          if ($rc != 0)
 | |
|          {
 | |
|           $rsp->{data}->[0] = "remoteshellexp failed sending keys to disablenodes.";
 | |
|           xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
| 
 | |
|          }
 | |
|       }
 | |
|     } else { # from user is not root or it is a device , always send private key
 | |
|        $ENV{'DSH_ENABLE_SSH'} = "YES";
 | |
|        my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$n_str);
 | |
|        if ($rc != 0)
 | |
|        {
 | |
|            $rsp->{data}->[0] = "remoteshellexp failed sending keys.";
 | |
|            xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
| 
 | |
|        }
 | |
|     }
 | |
| 
 | |
|     # must always check to see if worked, run test
 | |
|     my @testnodes=  split(",", $nodes[0]);
 | |
|     foreach my $n (@testnodes)
 | |
|     {
 | |
|        my $rc=
 | |
|      xCAT::RemoteShellExp->remoteshellexp("t",$::CALLBACK,"/usr/bin/ssh",$n);
 | |
|         if ($rc != 0)
 | |
|         {
 | |
|             push @badnodes, $n;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (@badnodes)
 | |
|     {
 | |
|         my $nstring = join ',', @badnodes;
 | |
|         $rsp->{data}->[0] =
 | |
|           "SSH setup failed for the following nodes: $nstring.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|         return @badnodes;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         $rsp->{data}->[0] = "$::REMOTE_SHELL setup is complete.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|         return 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    cpSSHFiles
 | |
| 
 | |
|            Builds authorized_keyfiles for root 
 | |
| 
 | |
|         Arguments:
 | |
|                install directory path
 | |
|         Returns:
 | |
| 
 | |
|         Globals:
 | |
|               $::CALLBACK
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
|                 xCAT::TableUtils->cpSSHFiles($dir);
 | |
| 
 | |
|         Comments:
 | |
|                 none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| sub cpSSHFiles
 | |
| {
 | |
|     my ($class, $SSHdir) = @_;
 | |
|     my ($cmd, $rc);
 | |
|     my $rsp = {};
 | |
|     if ($::VERBOSE)
 | |
|     {
 | |
|         $rsp->{data}->[0] = "Copying SSH Keys";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|     }
 | |
|     my $home = xCAT::Utils->getHomeDir("root");
 | |
| 
 | |
| 
 | |
|     if (xCAT::Utils->isMN()) {    # if on Management Node
 | |
|       if (!(-e "$home/.ssh/id_rsa.pub"))   # only using rsa
 | |
|       {
 | |
|           $rsp->{data}->[0] = "Public key id_rsa.pub was missing in the .ssh directory.";
 | |
|           xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|           return 1;
 | |
|       }
 | |
|       # copy to id_rsa public key to authorized_keys in the install directory
 | |
|       my $authorized_keys = "$SSHdir/authorized_keys";
 | |
|       # changed from  identity.pub
 | |
|       $cmd = " cp $home/.ssh/id_rsa.pub $authorized_keys";
 | |
|       xCAT::Utils->runcmd($cmd, 0);
 | |
|       $rsp = {};
 | |
|       if ($::RUNCMD_RC != 0)
 | |
|       {
 | |
|         $rsp->{data}->[0] = "$cmd failed.\n";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|         return (1);
 | |
| 
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         if ($::VERBOSE)
 | |
|         {
 | |
|             $rsp->{data}->[0] = "$cmd succeeded.\n";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|         }
 | |
|       }
 | |
|     } # end is MN
 | |
| 
 | |
|     # on MN and SN
 | |
|     # make tmp directory to hold authorized_keys for node transfer
 | |
|     if (!(-e "$home/.ssh/tmp")) {
 | |
|       $cmd = " mkdir $home/.ssh/tmp";
 | |
|       xCAT::Utils->runcmd($cmd, 0);
 | |
|       $rsp = {};
 | |
|       if ($::RUNCMD_RC != 0)
 | |
|       {
 | |
|         $rsp->{data}->[0] = "$cmd failed.\n";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|         return (1);
 | |
| 
 | |
|       }
 | |
|     }
 | |
|     # create authorized_keys file 
 | |
|     if (xCAT::Utils->isMN()) {    # if on Management Node
 | |
|       $cmd = " cp $home/.ssh/id_rsa.pub $home/.ssh/tmp/authorized_keys";
 | |
|     } else {  # SN
 | |
|       $cmd = " cp $home/.ssh/authorized_keys $home/.ssh/tmp/authorized_keys";
 | |
|     }
 | |
|     xCAT::Utils->runcmd($cmd, 0);
 | |
|     $rsp = {};
 | |
|     if ($::RUNCMD_RC != 0)
 | |
|     {
 | |
|         $rsp->{data}->[0] = "$cmd failed.\n";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|         return (1);
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         chmod 0600, "$home/.ssh/tmp/authorized_keys";
 | |
|         if ($::VERBOSE)
 | |
|         {
 | |
|             $rsp->{data}->[0] = "$cmd succeeded.\n";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return (0);
 | |
| }
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   GetNodeOSARCH
 | |
|         Reads the database for the OS and Arch of the input Node
 | |
|     Arguments:
 | |
| 		 Node
 | |
|     Returns:
 | |
|         $et->{'os'}
 | |
| 		$et->{'arch'}
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|          $master=(xCAT::TableUtils->GetNodeOSARCH($node))
 | |
|     Comments:
 | |
|         none
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub GetNodeOSARCH
 | |
| {
 | |
|     my ($class, $node) = @_;
 | |
|     my $typetab    = xCAT::Table->new('nodetype');
 | |
|     unless ($typetab)
 | |
|     {
 | |
|         xCAT::MsgUtils->message('S',
 | |
|                                 "Unable to open nodetype table.\n");
 | |
|         return 1;
 | |
|     }
 | |
|     my $et = $typetab->getNodeAttribs($node, ['os', 'arch']);
 | |
|     unless ($et and $et->{'os'} and $et->{'arch'})
 | |
|     {
 | |
|         xCAT::MsgUtils->message('S',
 | |
|                            "No os/arch setting in nodetype table for $node.\n");
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     return $et;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   logEventsToDatabase
 | |
|        Logs the given events info to the xCAT's 'eventlog' database 
 | |
|     Arguments:
 | |
|         arrayref -- A pointer to an array. Each element is a hash that contains an events.
 | |
|         The hash should contain the at least one of the following keys:
 | |
|           eventtime -- The format is "yyyy-mm-dd hh:mm:ss".
 | |
|                        If omitted, the current date and time will be used.
 | |
|           monitor  -- The name of the monitor that monitors this event.
 | |
|           monnode -- The node that monitors this event.
 | |
|           node -- The node where the event occurred.
 | |
|           application -- The application that reports the event.
 | |
|           component -- The component where the event occurred.
 | |
|           id -- The location or the resource name where the event occurred.
 | |
|           severity -- The severity of the event. Valid values are: informational, warning, critical.
 | |
|           message -- The full description of the event.
 | |
| 	  rawdata -- The data that associated with the event.         
 | |
|   Returns:
 | |
|        (ret code, error message) 
 | |
|   Example:
 | |
|     my  @a=();
 | |
|     my $event={
 | |
|         eventtime=>"2009-07-28 23:02:03",
 | |
|         node => 'node1',
 | |
|         rawdata => 'kjdlkfajlfjdlksaj',
 | |
|     };
 | |
|     push (@a, $event);
 | |
| 
 | |
|     my $event1={
 | |
|         node => 'cu03cp',
 | |
|         monnode => 'cu03sv',
 | |
|         application => 'RMC',
 | |
|         component => 'IBM.Sensor',
 | |
|         id => 'AIXErrorLogSensor',
 | |
|         severity => 'warning',
 | |
|     };
 | |
|     push(@a, $event1);
 | |
|     xCAT::TableUtils->logEventsToDatabase(\@a);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub logEventsToDatabase
 | |
| {
 | |
|     my $pEvents = shift;
 | |
|     if (($pEvents) && ($pEvents =~ /xCAT::TableUtils/))
 | |
|     {
 | |
|         $pEvents = shift;
 | |
|     }
 | |
| 
 | |
|     if (($pEvents) && (@$pEvents > 0))
 | |
|     {
 | |
|         my $currtime;
 | |
|         my $tab = xCAT::Table->new("eventlog", -create => 1, -autocommit => 0);
 | |
|         if (!$tab)
 | |
|         {
 | |
|             return (1, "The evnetlog table cannot be opened.");
 | |
|         }
 | |
| 
 | |
|         foreach my $event (@$pEvents)
 | |
|         {
 | |
| 
 | |
|             #create event time if it does not exist
 | |
|             if (!exists($event->{eventtime}))
 | |
|             {
 | |
|                 if (!$currtime)
 | |
|                 {
 | |
|                     my (
 | |
|                         $sec,  $min,  $hour, $mday, $mon,
 | |
|                         $year, $wday, $yday, $isdst
 | |
|                       )
 | |
|                       = localtime(time);
 | |
|                     $currtime = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
 | |
|                                         $year + 1900, $mon + 1, $mday, 
 | |
|                                         $hour, $min, $sec);
 | |
|                 }
 | |
|                 $event->{eventtime} = $currtime;
 | |
|             }
 | |
|             my @ret = $tab->setAttribs(undef, $event);
 | |
|             if (@ret > 1) { return (1, $ret[1]); }
 | |
|         }
 | |
|         $tab->commit;
 | |
|     }
 | |
| 
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   logEventsToTealDatabase
 | |
|        Logs the given events info to the TEAL's 'x_tealeventlog' database 
 | |
|     Arguments:
 | |
|         arrayref -- A pointer to an array. Each element is a hash that contains an events.
 | |
|   Returns:
 | |
|        (ret code, error message) 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub logEventsToTealDatabase
 | |
| {
 | |
|     my $pEvents = shift;
 | |
|     if (($pEvents) && ($pEvents =~ /xCAT::TableUtils/))
 | |
|     {
 | |
|         $pEvents = shift;
 | |
|     }
 | |
| 
 | |
|     if (($pEvents) && (@$pEvents > 0))
 | |
|     {
 | |
|         my $currtime;
 | |
|         my $tab = xCAT::Table->new("x_tealeventlog", -create => 1, -autocommit => 0);
 | |
|         if (!$tab)
 | |
|         {
 | |
|             return (1, "The x_tealeventlog table cannot be opened.");
 | |
|         }
 | |
| 
 | |
|         foreach my $event (@$pEvents)
 | |
|         {
 | |
|             my @ret = $tab->setAttribs(undef, $event);
 | |
|             if (@ret > 1) { return (1, $ret[1]); }
 | |
|         }
 | |
|         $tab->commit;
 | |
|     }
 | |
| 
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  setAppStatus
 | |
|     Description:
 | |
|         Set an AppStatus value for a specific application in the nodelist
 | |
|         appstatus attribute for a list of nodes
 | |
|     Arguments:
 | |
|         @nodes
 | |
|         $application
 | |
|         $status
 | |
|     Returns:
 | |
|         Return result of call to setNodesAttribs
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         xCAT::TableUtils->setAppStatus(\@nodes,$application,$status);
 | |
|     Comments:
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub setAppStatus
 | |
| {
 | |
| 
 | |
|     my ($class, $nodes_ref, $application, $status) = @_;
 | |
|     my @nodes = @$nodes_ref;
 | |
| 
 | |
|     #get current local time to set in appstatustime attribute
 | |
|     my (
 | |
|         $sec,  $min,  $hour, $mday, $mon,
 | |
|         $year, $wday, $yday, $isdst
 | |
|         )
 | |
|         = localtime(time);
 | |
|     my $currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
 | |
|                            $mon + 1, $mday, $year + 1900,
 | |
|                            $hour, $min, $sec);
 | |
| 
 | |
|     my $nltab = xCAT::Table->new('nodelist');
 | |
|     my $nodeappstat = $nltab->getNodesAttribs(\@nodes,['appstatus']);
 | |
| 
 | |
|     my %new_nodeappstat;
 | |
|     foreach my $node (keys %$nodeappstat) {
 | |
|         if ( $node =~ /^\s*$/ ) { next; }  # Skip blank node names 
 | |
|         my $new_appstat = "";
 | |
|         my $changed = 0;
 | |
| 
 | |
|         # Search current appstatus and change if app entry exists
 | |
|         my $cur_appstat = $nodeappstat->{$node}->[0]->{appstatus};
 | |
|         if ($cur_appstat) {
 | |
|             my @appstatus_entries = split(/,/,$cur_appstat);
 | |
|             foreach my $appstat (@appstatus_entries) {
 | |
|                 my ($app, $stat) = split(/=/,$appstat);
 | |
|                 if ($app eq $application) {
 | |
|                    $new_appstat .= ",$app=$status";
 | |
|                    $changed = 1;
 | |
|                 } else {
 | |
|                    $new_appstat .= ",$appstat";
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         # If no app entry exists, add it
 | |
|         if (!$changed){
 | |
|            $new_appstat .= ",$application=$status";
 | |
|         }
 | |
|         $new_appstat =~ s/^,//;
 | |
|         $new_nodeappstat{$node}->{appstatus} = $new_appstat;
 | |
|         $new_nodeappstat{$node}->{appstatustime} = $currtime;
 | |
|     }
 | |
| 
 | |
|     return $nltab->setNodesAttribs(\%new_nodeappstat);
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  setUpdateStatus
 | |
|     Description:
 | |
|         Set the updatestatus  attribute for a list of nodes during "updatenode"
 | |
|     Arguments:
 | |
|         @nodes
 | |
|         $status
 | |
|     Returns:
 | |
|         none
 | |
|         
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         xCAT::TableUtils->setUpdateStatus(\@nodes,$status);
 | |
|     Comments:
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub setUpdateStatus
 | |
| {
 | |
| 
 | |
| 
 | |
|     my ($class, $nodes_ref, $status) = @_;
 | |
|     my @nodes = @$nodes_ref;
 | |
| 
 | |
| 
 | |
| 
 | |
|     #get current local time to set in Updatestatustime attribute
 | |
|     my (
 | |
|         $sec,  $min,  $hour, $mday, $mon,
 | |
|         $year, $wday, $yday, $isdst
 | |
|         )
 | |
|         = localtime(time);
 | |
|     my $currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
 | |
|                            $mon + 1, $mday, $year + 1900,
 | |
|                            $hour, $min, $sec);
 | |
| 
 | |
|     my $nltab = xCAT::Table->new('nodelist');
 | |
|     if($nltab){
 | |
| 		if(@nodes>0){
 | |
| 		   my %updates;
 | |
| 
 | |
|                    foreach my $node (@nodes)
 | |
|                    {
 | |
|                         $updates{$node}{'updatestatus'} = $status;
 | |
|                         $updates{$node}{'updatestatustime'} = $currtime;
 | |
|                    }
 | |
| 
 | |
|                    $nltab->setNodesAttribs(\%updates);
 | |
|  		}
 | |
|               $nltab->close;	
 | |
| 	}
 | |
|    return;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  getAppStatus
 | |
|     Description:
 | |
|         Get an AppStatus value for a specific application from the
 | |
|         nodelist appstatus attribute for a list of nodes
 | |
|     Arguments:
 | |
|         @nodes
 | |
|         $application
 | |
|     Returns:
 | |
|         a hashref of nodes set to application status value
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         my $appstatus = $xCAT::TableUtils->getAppStatus(\@nodes,$application);
 | |
|        my $node1_status = $appstatus->{node1};
 | |
|     Comments:
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub getAppStatus
 | |
| {
 | |
| 
 | |
|     my ($class, $nodes_ref, $application) = @_;
 | |
|     my @nodes = @$nodes_ref;
 | |
| 
 | |
|     my $nltab = xCAT::Table->new('nodelist');
 | |
|     my $nodeappstat = $nltab->getNodesAttribs(\@nodes,['appstatus']);
 | |
| 
 | |
|     my $ret_nodeappstat;
 | |
|     foreach my $node (keys %$nodeappstat) {
 | |
|         my $cur_appstat = $nodeappstat->{$node}->[0]->{appstatus};
 | |
|         my $found = 0;
 | |
|         if ($cur_appstat) {
 | |
|             my @appstatus_entries = split(/,/,$cur_appstat);
 | |
|             foreach my $appstat (@appstatus_entries) {
 | |
|                 my ($app, $stat) = split(/=/,$appstat);
 | |
|                 if ($app eq $application) {
 | |
|                    $ret_nodeappstat->{$node} = $stat;
 | |
|                    $found = 1;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         # If no app entry exists, return empty
 | |
|         if (!$found){
 | |
|            $ret_nodeappstat->{$node} = "";
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return $ret_nodeappstat;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-----------------------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|   get_site_attribute
 | |
| 
 | |
| 	Arguments:
 | |
| 
 | |
| 	Returns:
 | |
| 	    The value of the attribute requested from the site table
 | |
| 	Globals:
 | |
| 		none
 | |
| 	Error:
 | |
| 		undef
 | |
| 	Example:
 | |
| 	   @attr=xCAT::TableUtils->get_site_attribute($attribute);
 | |
| 	Comments:
 | |
| 		none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #------------------------------------------------------------------------
 | |
| sub get_site_attribute
 | |
| {
 | |
|     my ($class, $attr) = @_;
 | |
|     
 | |
|     my $values;
 | |
|     if (defined($::XCATSITEVALS{$attr})) {
 | |
|         $values = ($::XCATSITEVALS{$attr});
 | |
|     } else {
 | |
|         my $sitetab = xCAT::Table->new('site');
 | |
|         if ($sitetab)
 | |
|         {
 | |
|             (my $ref) = $sitetab->getAttribs({key => $attr}, 'value');
 | |
|             if ($ref)
 | |
|             {
 | |
|                 $values = $ref->{value};
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             xCAT::MsgUtils->message("E", " Could not read the site table\n");
 | |
| 
 | |
|         }
 | |
|         $sitetab->close;
 | |
|     }
 | |
|     return $values;
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    getInstallDir
 | |
| 
 | |
|         Get location of the directory, used to hold the node deployment packages.
 | |
| 
 | |
|         Arguments:
 | |
|                 none
 | |
|         Returns:
 | |
|                 path to install directory defined at site.installdir.
 | |
|         Globals:
 | |
|                 none
 | |
|         Error:
 | |
|                 none
 | |
|         Example:
 | |
|                 $installdir = xCAT::TableUtils->getInstallDir();
 | |
|         Comments:
 | |
|                 none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| sub getInstallDir
 | |
| {
 | |
|     # Default installdir location. Used by default in most Linux distros.
 | |
|     my $installdir = "/install";
 | |
| 
 | |
|     # Try to lookup real installdir place.
 | |
|     my @installdir1 = xCAT::TableUtils->get_site_attribute("installdir");
 | |
| 
 | |
|     # Use fetched value, incase successful database lookup.
 | |
|     if ($installdir1[0])
 | |
|     {
 | |
|         $installdir = $installdir1[0];
 | |
|     }
 | |
| 
 | |
|     return $installdir;
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    getTftpDir
 | |
| 
 | |
|         Get location of the directory, used to hold network boot files.
 | |
| 
 | |
|         Arguments:
 | |
|                 none
 | |
|         Returns:
 | |
|                 path to TFTP directory defined at site.tftpdir.
 | |
|         Globals:
 | |
|                 none
 | |
|         Error:
 | |
|                 none
 | |
|         Example:
 | |
|                 $tftpdir = xCAT::TableUtils->getTftpDir();
 | |
|         Comments:
 | |
|                 none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| sub getTftpDir
 | |
| {
 | |
|     # Default tftpdir location. Used by default in most Linux distros.
 | |
|     my $tftpdir = "/tftpboot";
 | |
| 
 | |
|     # Try to lookup real tftpdir place.
 | |
|     my @tftpdir1 = xCAT::TableUtils->get_site_attribute("tftpdir");
 | |
| 
 | |
|     # Use fetched value, incase successful database lookup.
 | |
|     if ($tftpdir1[0])
 | |
|     {
 | |
|         $tftpdir = $tftpdir1[0];
 | |
|     }
 | |
| 
 | |
|     return $tftpdir;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   GetMasterNodeName
 | |
|         Reads the database for the Master node name for the input node
 | |
|     Arguments:
 | |
| 		 Node
 | |
|     Returns:
 | |
|         MasterHostName
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|          $master=(xCAT::TableUtils->GetMasterNodeName($node))
 | |
|     Comments:
 | |
|         none
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub GetMasterNodeName
 | |
| {
 | |
|     my ($class, $node) = @_;
 | |
|     my $master;
 | |
|     my $noderestab = xCAT::Table->new('noderes');
 | |
|     unless ($noderestab)
 | |
|     {
 | |
|         xCAT::MsgUtils->message('S',
 | |
|                                 "Unable to open noderes  table.\n");
 | |
|         return 1;
 | |
|     }
 | |
|     my @masters = xCAT::TableUtils->get_site_attribute("master"); 
 | |
|     $master = $masters[0];
 | |
|     
 | |
|     my $et = $noderestab->getNodeAttribs($node, ['xcatmaster']);
 | |
|     if ($et and $et->{'xcatmaster'})
 | |
|     {
 | |
|         $master = $et->{'xcatmaster'};
 | |
|     }
 | |
|     unless ($master)
 | |
|     {
 | |
|         xCAT::MsgUtils->message('S', "Unable to identify master for $node.\n");
 | |
|         $noderestab->close;
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     $noderestab->close;
 | |
|     return $master;
 | |
| }
 | |
| 
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| =head3 create_postscripts_tar
 | |
| 
 | |
|      This routine will tar and compress the /install/postscripts directory
 | |
| 	 and place in /install/autoinst/xcat_postscripts.Z
 | |
| 
 | |
|      input: none
 | |
| 	 output:
 | |
| 	 example: $rc=xCAT::TableUtils->create_postscripts_tar();
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub create_postscripts_tar
 | |
| {
 | |
|     my ($class) = @_;
 | |
|     my $installdir = xCAT::TableUtils->getInstallDir();
 | |
|     my $cmd;
 | |
|     if (!(-e "$installdir/autoinst"))
 | |
|     {
 | |
|         mkdir("$installdir/autoinst");
 | |
|     }
 | |
| 
 | |
|     $cmd =
 | |
|       "cd $installdir/postscripts; tar -cf $installdir/autoinst/xcatpost.tar * .ssh/* _xcat/*; gzip -f $installdir/autoinst/xcatpost.tar";
 | |
|     my @result = xCAT::Utils->runcmd($cmd, 0);
 | |
|     if ($::RUNCMD_RC != 0)
 | |
|     {
 | |
|         xCAT::MsgUtils->message("S", "Error from $cmd\n");
 | |
|         return $::RUNCMD_RC;
 | |
|     }
 | |
| 
 | |
|     # for AIX add an entry to the /etc/tftpaccess.ctrl file so
 | |
|     #	we can tftp the tar file from the node
 | |
|     if (xCAT::Utils->isAIX())
 | |
|     {
 | |
|         my $tftpctlfile = "/etc/tftpaccess.ctl";
 | |
|         my $entry       = "allow:$installdir/autoinst/xcatpost.tar.gz";
 | |
| 
 | |
|         # see if there is already an entry
 | |
|         my $cmd = "cat $tftpctlfile | grep xcatpost";
 | |
|         my @result = xCAT::Utils->runcmd("$cmd", -1);
 | |
|         if ($::RUNCMD_RC != 0)
 | |
|         {
 | |
| 
 | |
|             # not found so add it
 | |
|             unless (open(TFTPFILE, ">>$tftpctlfile"))
 | |
|             {
 | |
|                 xCAT::MsgUtils->message("S", "Could not open $tftpctlfile.\n");
 | |
|                 return $::RUNCMD_RC;
 | |
|             }
 | |
| 
 | |
|             print TFTPFILE $entry;
 | |
| 
 | |
|             close(TFTPFILE);
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| =head3 get_site_Master
 | |
| 
 | |
|      Reads the site table for the Master attribute and returns it.
 | |
|      input: none
 | |
|      output : value of site.Master attribute , blank is an error
 | |
| 	 example: $Master =xCAT::TableUtils->get_site_Master();
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub get_site_Master
 | |
| {
 | |
|     if ($::XCATSITEVALS{master}) {
 | |
|         return $::XCATSITEVALS{master};
 | |
|     }
 | |
|     my $Master;
 | |
|     my $sitetab = xCAT::Table->new('site');
 | |
|     (my $et) = $sitetab->getAttribs({key => "master"}, 'value');
 | |
|     if ($et and $et->{value})
 | |
|     {
 | |
|         $Master = $et->{value};
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| # this msg can be missleading
 | |
| #        xCAT::MsgUtils->message('E',
 | |
| #                           "Unable to read site table for Master attribute.\n");
 | |
|     }
 | |
|     return $Master;
 | |
| }
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3 checkCredFiles 
 | |
|         Checks the various credential files on the Management Node to
 | |
| 		make sure the permission are correct for using and transferring
 | |
| 		to the nodes and service nodes.
 | |
| 		Also removes /install/postscripts/etc/xcat/cfgloc if found
 | |
|     Arguments:
 | |
|       $callback 
 | |
|     Returns:
 | |
|         0 - ok
 | |
|     Globals:
 | |
|         none 
 | |
|     Error:
 | |
|          warnings of possible missing files  and directories
 | |
|     Example:
 | |
|          my $rc=xCAT::TableUtils->checkCreds
 | |
|     Comments:
 | |
|         none
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| sub checkCredFiles
 | |
| {
 | |
|     my $lib = shift;
 | |
|     my $cb  = shift;
 | |
|     my $installdir = xCAT::TableUtils->getInstallDir();
 | |
|     my $dir = "$installdir/postscripts/_xcat";
 | |
|     if (-d $dir)
 | |
|     {
 | |
|         my $file = "$dir/ca.pem";
 | |
|         if (-e $file)
 | |
|         {
 | |
| 
 | |
|             my $cmd = "/bin/chmod 0644 $file";
 | |
|             my $outref = xCAT::Utils->runcmd("$cmd", 0);
 | |
|             if ($::RUNCMD_RC != 0)
 | |
|             {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Error on command: $cmd";
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
| 
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {    # ca.pem missing
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "Error: $file is missing. Run xcatconfig (no force)";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Error: $dir is missing.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     $dir = "$installdir/postscripts/ca";
 | |
|     if (-d $dir)
 | |
|     {
 | |
|         my $file = "$dir/ca-cert.pem";
 | |
|         if (-e $file)
 | |
|         {
 | |
| 
 | |
|             my $cmd = "/bin/chmod 0644 $file";
 | |
|             my $outref = xCAT::Utils->runcmd("$cmd", 0);
 | |
|             if ($::RUNCMD_RC != 0)
 | |
|             {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Error on command: $cmd";
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
| 
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {    # ca_cert.pem missing
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "Error: $file is missing. Run xcatconfig (no force)";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Error: $dir is missing.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     # ssh hostkeys
 | |
|     $dir = "$installdir/postscripts/hostkeys";
 | |
|     if (-d $dir)
 | |
|     {
 | |
|         my $file = "$dir/ssh_host_key.pub";
 | |
|         if (-e $file)
 | |
|         {
 | |
|             my $file2  = "$dir/*.pub";                     # all public keys
 | |
|             my $cmd    = "/bin/chmod 0644 $file2";
 | |
|             my $outref = xCAT::Utils->runcmd("$cmd", 0);
 | |
|             if ($::RUNCMD_RC != 0)
 | |
|             {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Error on command: $cmd";
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
| 
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {                                                  # hostkey missing
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "Error: $file is missing. Run xcatconfig (no force)";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Error: $dir is missing.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|     }
 | |
|     # ssh hostkeys
 | |
|     $dir = "/etc/xcat/hostkeys";
 | |
|     if (-d $dir)
 | |
|     {
 | |
|         my $file = "$dir/ssh_host_key.pub";
 | |
|         if (-e $file)
 | |
|         {
 | |
|             my $file2  = "$dir/*.pub";                     # all public keys
 | |
|             my $cmd    = "/bin/chmod 0644 $file2";
 | |
|             my $outref = xCAT::Utils->runcmd("$cmd", 0);
 | |
|             if ($::RUNCMD_RC != 0)
 | |
|             {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Error on command: $cmd";
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
| 
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {                                                  # hostkey missing
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "Error: $file is missing. Run xcatconfig (no force)";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Error: $dir is missing.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|     }
 | |
| 
 | |
|     # ssh directory
 | |
|     $dir = "$installdir/postscripts/_ssh";
 | |
| 
 | |
|     if (-d $dir)
 | |
|     {
 | |
|         my $file = "$dir/authorized_keys";
 | |
|         if (-e $file)
 | |
|         {
 | |
|             my $file2  = "$dir/authorized_keys*";
 | |
|             my $cmd    = "/bin/chmod 0644 $file2";
 | |
|             my $outref = xCAT::Utils->runcmd("$cmd", 0);
 | |
|             if ($::RUNCMD_RC != 0)
 | |
|             {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] = "Error on command: $cmd";
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
| 
 | |
|             }
 | |
| 
 | |
|             # make install script executable
 | |
|             $file2 = "$dir/copy.sh";
 | |
|             if (-e $file2)
 | |
|             {
 | |
|                 my $cmd = "/bin/chmod 0744 $file2";
 | |
|                 my $outref = xCAT::Utils->runcmd("$cmd", 0);
 | |
|                 if ($::RUNCMD_RC != 0)
 | |
|                 {
 | |
|                     my $rsp = {};
 | |
|                     $rsp->{data}->[0] = "Error on command: $cmd";
 | |
|                     xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
| 
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {    # authorized keys missing
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "Error: $file is missing. Run xcatconfig (no force)";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "Error: $dir is missing.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
|     }
 | |
| 
 | |
|     # remove any old cfgloc files
 | |
|     my $file = "$installdir/postscripts/etc/xcat/cfgloc";
 | |
|     if (-e $file)
 | |
|     {
 | |
| 
 | |
|         my $cmd = "/bin/rm  $file";
 | |
|         my $outref = xCAT::Utils->runcmd("$cmd", 0);
 | |
|         if ($::RUNCMD_RC != 0)
 | |
|         {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "Error on command: $cmd";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $cb);
 | |
| 
 | |
|         }
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3  enableSSH 
 | |
|     Description:
 | |
|         Reads the site.sshbetweennodes attribute and determines
 | |
|         if the input node should be enabled to ssh between nodes 
 | |
|     Arguments:
 | |
|         $node 
 | |
|     Returns:
 | |
|        1 = enable ssh
 | |
|        0 = do not enable ssh 
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|         none
 | |
|     Example:
 | |
|         my $eable = xCAT::TableUtils->enablessh($node);
 | |
|     Comments:
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub enablessh 
 | |
| {
 | |
| 
 | |
|     my ($class, $node) = @_;
 | |
|     my $enablessh=1;
 | |
|     
 | |
|     if( %::GLOBAL_SN_HASH ) {
 | |
|         if ($::GLOBAL_SN_HASH{$node} == 1) {
 | |
|             $enablessh=1;   # service nodes always enabled
 | |
| 
 | |
|         } 
 | |
|     } else { 
 | |
|         if (xCAT::Utils->isSN($node)) 
 | |
|         {
 | |
|             $enablessh=1;   # service nodes always enabled
 | |
|         }
 | |
|         else
 | |
|        {
 | |
| 
 | |
|         # if not a service node we need to check, before enabling
 | |
|         my $values;
 | |
|         my @vals = xCAT::TableUtils->get_site_attribute("sshbetweennodes");
 | |
|         $values = $vals[0];
 | |
|         if ($values) {
 | |
|             my @groups = split(/,/, $values);
 | |
|             if (grep(/^ALLGROUPS$/, @groups))
 | |
|             {
 | |
|               $enablessh=1;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (grep(/^NOGROUPS$/, @groups))
 | |
|                 {
 | |
|                       $enablessh=0;
 | |
|                 }
 | |
|                 else
 | |
|                 {    # check to see if the node is a member of a group
 | |
|                     my $ismember = 0;
 | |
|                     foreach my $group (@groups)
 | |
|                     {
 | |
|                         $ismember = xCAT::Utils->isMemberofGroup($node, $group);
 | |
|                         if ($ismember == 1)
 | |
|                         {
 | |
|                             last;
 | |
|                         }
 | |
|                     }
 | |
|                     if ($ismember == 1)
 | |
|                     {
 | |
|                         $enablessh=1;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         $enablessh=0;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|          }
 | |
|          else
 | |
|          {    # does not exist, set default
 | |
|             $enablessh=1;
 | |
| 
 | |
|          }
 | |
|        }
 | |
|     }
 | |
|     return $enablessh;
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| =head3 getrootimage
 | |
|     Get the directory of root image for a node; 
 | |
|     Note: This subroutine only works for diskless node
 | |
| 
 | |
|     Arguments:
 | |
|       $node
 | |
|     Returns:
 | |
|       string - directory of the root image
 | |
|       undef - this is not a diskless node or the root image does not existed
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|     Example:
 | |
|          my $node_syncfile=xCAT::TableUtils->getrootimage($node);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub getrootimage()
 | |
| {
 | |
|   my $node = shift;
 | |
|   my $installdir = xCAT::TableUtils->getInstallDir();
 | |
|   if (($node) && ($node =~ /xCAT::TableUtils/))	
 | |
|   {
 | |
|     $node = shift;
 | |
|   }
 | |
|       # 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->getNodeAttribs($node, ['profile','os','arch']);
 | |
|   my $profile = $nodetype_v->{'profile'};
 | |
|   my $os = $nodetype_v->{'os'};
 | |
|   my $arch = $nodetype_v->{'arch'};
 | |
| 
 | |
|   if ($^O eq "linux") {
 | |
|     my $rootdir = "$installdir/netboot/$os/$arch/$profile/rootimg/";
 | |
|     if (-d $rootdir) {
 | |
|       return $rootdir;
 | |
|     } else {
 | |
|       return undef;
 | |
|     }
 | |
|   } else {
 | |
|     # For AIX
 | |
|   }
 | |
| }
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| =head3 getimagenames
 | |
|     Get an array of osimagenames that correspond to the input node array; 
 | |
| 
 | |
|     Arguments:
 | |
|      Array of nodes 
 | |
|     Returns:
 | |
|       array of all the osimage names that are the provmethod for the nodes 
 | |
|       undef - no osimage names 
 | |
|     Globals:
 | |
|         none
 | |
|     Error:
 | |
|     Example:
 | |
|          my @imagenames=xCAT::TableUtils->getimagenames(\@nodes);
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub getimagenames()
 | |
| {
 | |
|   my ($class, $nodes)=@_;
 | |
|   my @nodelist = @$nodes;
 | |
|    my $nodetab = xCAT::Table->new('nodetype');
 | |
|     my $images  =
 | |
|       $nodetab->getNodesAttribs(\@nodelist, ['node', 'provmethod', 'profile']);
 | |
|     my @imagenames;
 | |
|     foreach my $node (@nodelist)
 | |
|     {
 | |
|         my $imgname;
 | |
|         if ($images->{$node}->[0]->{provmethod})
 | |
|         {
 | |
|             $imgname = $images->{$node}->[0]->{provmethod};
 | |
|         }
 | |
|         elsif ($images->{$node}->[0]->{profile})
 | |
|         {
 | |
|             $imgname = $images->{$node}->[0]->{profile};
 | |
|         }
 | |
|         # if the node has an image
 | |
|         if ($imgname) {
 | |
|           if (!grep(/^$imgname$/, @imagenames)) # not already on the list
 | |
|           {
 | |
|              push @imagenames, $imgname;   # add to the array
 | |
|           }
 | |
|         }
 | |
|     }
 | |
|     $nodetab->close;
 | |
|     return @imagenames;
 | |
| }
 | |
| 1;
 |