git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@13524 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			1581 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1581 lines
		
	
	
		
			43 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";
 | 
						|
#-----------------------------------------------------------------------
 | 
						|
 | 
						|
=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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    my ($class, $node) = @_;
 | 
						|
    my $noderestab = xCAT::Table->new('noderes');
 | 
						|
    my $typetab    = xCAT::Table->new('nodetype');
 | 
						|
    unless ($noderestab and $typetab)
 | 
						|
    {
 | 
						|
        xCAT::MsgUtils->message('S',
 | 
						|
                                "Unable to open noderes or 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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
 | 
						|
    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  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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
 | 
						|
    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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    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
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    my ($class, $node) = @_;
 | 
						|
    my $master;
 | 
						|
    my $noderestab = xCAT::Table->new('noderes');
 | 
						|
    my $typetab    = xCAT::Table->new('nodetype');
 | 
						|
    unless ($noderestab and $typetab)
 | 
						|
    {
 | 
						|
        xCAT::MsgUtils->message('S',
 | 
						|
                                "Unable to open noderes or nodetype table.\n");
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    #my $sitetab = xCAT::Table->new('site');
 | 
						|
    #(my $et) = $sitetab->getAttribs({key => "master"}, 'value');
 | 
						|
    #if ($et and $et->{value})
 | 
						|
    #{
 | 
						|
    #    $master = $et->{value};
 | 
						|
    #}
 | 
						|
    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");
 | 
						|
        #$sitetab->close;
 | 
						|
        $noderestab->close;
 | 
						|
        $typetab->close;
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    #$sitetab->close;
 | 
						|
    $noderestab->close;
 | 
						|
    $typetab->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};
 | 
						|
    }
 | 
						|
    require xCAT::Table;
 | 
						|
    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 
 | 
						|
{
 | 
						|
 | 
						|
    require xCAT::Table;
 | 
						|
    my ($class, $node) = @_;
 | 
						|
    my $enablessh=1;
 | 
						|
    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;
 | 
						|
	#if (keys %::XCATSITEVALS) {
 | 
						|
	#	$values=$::XCATSITEVALS{sshbetweennodes};
 | 
						|
	#} else {
 | 
						|
	#        my $sitetab    = xCAT::Table->new('site');
 | 
						|
	#        my $attr = "sshbetweennodes";
 | 
						|
	#        my $ref = $sitetab->getAttribs({key => $attr}, 'value');
 | 
						|
	#        if ($ref) {
 | 
						|
        #    	   $values = $ref->{value};
 | 
						|
	#        }
 | 
						|
 	#}
 | 
						|
        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()
 | 
						|
{
 | 
						|
  require xCAT::Table;
 | 
						|
  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
 | 
						|
  }
 | 
						|
}
 | 
						|
1;
 |