git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@14071 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			826 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			826 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
#!/usr/bin/env perl
 | 
						|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
package xCAT::ServiceNodeUtils;
 | 
						|
 | 
						|
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;
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 readSNInfo
 | 
						|
 | 
						|
  Read resource, NFS server, Master node, OS an ARCH from the database
 | 
						|
  for the service node
 | 
						|
 | 
						|
  Input: service nodename
 | 
						|
  Output: Masternode, OS and ARCH
 | 
						|
  Example:
 | 
						|
    xCAT::ServiceNodeUtils->readSNInfo;
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub readSNInfo
 | 
						|
{
 | 
						|
    my ($class, $nodename) = @_;
 | 
						|
    my $rc = 0;
 | 
						|
    my $et;
 | 
						|
    my $masternode;
 | 
						|
    my $os;
 | 
						|
    my $arch;
 | 
						|
    $rc = xCAT::Utils->exportDBConfig();
 | 
						|
    if ($rc == 0)
 | 
						|
    {
 | 
						|
 | 
						|
        if ($nodename)
 | 
						|
        {
 | 
						|
            $masternode = xCAT::TableUtils->GetMasterNodeName($nodename);
 | 
						|
            if (!($masternode))
 | 
						|
            {
 | 
						|
                xCAT::MsgUtils->message('S',
 | 
						|
                                   "Could not get Master for node $nodename\n");
 | 
						|
                return 1;
 | 
						|
            }
 | 
						|
 | 
						|
            $et = xCAT::TableUtils->GetNodeOSARCH($nodename);
 | 
						|
            if ($et == 1)
 | 
						|
            {
 | 
						|
                xCAT::MsgUtils->message('S',
 | 
						|
                                  "Could not get OS/ARCH for node $nodename\n");
 | 
						|
                return 1;
 | 
						|
            }
 | 
						|
            if (!($et->{'os'} || $et->{'arch'}))
 | 
						|
            {
 | 
						|
                xCAT::MsgUtils->message('S',
 | 
						|
                                  "Could not get OS/ARCH for node $nodename\n");
 | 
						|
                return 1;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        $et->{'master'} = $masternode;
 | 
						|
        return $et;
 | 
						|
    }
 | 
						|
    return $rc;
 | 
						|
}
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 isServiceReq
 | 
						|
 | 
						|
 | 
						|
  Checks the service node table in the database to see 
 | 
						|
  if input Service should be setup on the
 | 
						|
  input service node
 | 
						|
 | 
						|
  Input:servicenodename,ipaddres(s) and hostnames of service node
 | 
						|
  Output:
 | 
						|
        array of services to setup  for this service node
 | 
						|
    Globals:
 | 
						|
        $::RUNCMD_RC = 0; good
 | 
						|
        $::RUNCMD_RC = 1; error 
 | 
						|
    Error:
 | 
						|
        none
 | 
						|
    Example:
 | 
						|
      @servicestosetup=xCAT::ServiceNodeUtils->isServiceReq($servicenodename, @serviceip) { blah; }
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub isServiceReq
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    my ($class, $servicenodename, $serviceip) = @_;
 | 
						|
 | 
						|
    # list of all services from service node table
 | 
						|
    # note this must be updated if more services added
 | 
						|
    my @services = (
 | 
						|
                    "nameserver", "dhcpserver", "tftpserver", "nfsserver",
 | 
						|
                    "conserver",  "monserver",  "ldapserver", "ntpserver",
 | 
						|
                    "ftpserver",  "ipforward"
 | 
						|
                    );
 | 
						|
 | 
						|
    my @ips = @$serviceip;    # list of service node ip addresses and names
 | 
						|
    my $rc  = 0;
 | 
						|
 | 
						|
    $rc = xCAT::Utils->exportDBConfig();    # export DB env
 | 
						|
    if ($rc != 0)
 | 
						|
    {
 | 
						|
        xCAT::MsgUtils->message('S', "Unable export DB environment.\n");
 | 
						|
        $::RUNCMD_RC = 1;
 | 
						|
        return;
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    # get handle to servicenode table
 | 
						|
    my $servicenodetab = xCAT::Table->new('servicenode');
 | 
						|
    unless ($servicenodetab)
 | 
						|
    {
 | 
						|
        xCAT::MsgUtils->message('S', "Unable to open servicenode table.\n");
 | 
						|
        $::RUNCMD_RC = 1;
 | 
						|
        return;    # do not setup anything
 | 
						|
    }
 | 
						|
 | 
						|
    my @process_service_list = ();
 | 
						|
 | 
						|
    # read all the nodes from the table, for each service
 | 
						|
    foreach my $service (@services)
 | 
						|
    {
 | 
						|
        my @snodelist = $servicenodetab->getAllNodeAttribs([$service]);
 | 
						|
 | 
						|
        foreach $serviceip (@ips)    # check the table for this servicenode
 | 
						|
        {
 | 
						|
            foreach my $node (@snodelist)
 | 
						|
 | 
						|
            {
 | 
						|
                if ($serviceip eq $node->{'node'})
 | 
						|
                {                    # match table entry
 | 
						|
                    if ($node->{$service})
 | 
						|
                    {                # returns service, only if set
 | 
						|
                        my $value = $node->{$service};
 | 
						|
                        $value =~ tr/a-z/A-Z/;    # convert to upper
 | 
						|
                             # value 1 or yes  then we setup the service
 | 
						|
                        if (($value eq "1") || ($value eq "YES"))
 | 
						|
                        {
 | 
						|
                            push @process_service_list,
 | 
						|
                              $service;    # found service to setup
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    $servicenodetab->close;
 | 
						|
 | 
						|
    $::RUNCMD_RC = 0;
 | 
						|
    return @process_service_list;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 getAllSN 
 | 
						|
 
 | 
						|
    Returns an array of all service nodes from service node table 
 | 
						|
 | 
						|
    Arguments:
 | 
						|
       ALL"  - will also return the management node in the array, if
 | 
						|
        if has been defined in the servicenode table 
 | 
						|
    Returns:
 | 
						|
		array of Service Nodes or empty array, if none
 | 
						|
    Globals:
 | 
						|
        none
 | 
						|
    Error:
 | 
						|
        1 - error
 | 
						|
    Example:
 | 
						|
         @SN=xCAT::ServiceNodeUtils->getAllSN
 | 
						|
         @allSN=xCAT::ServiceNodeUtils->getAllSN("ALL")
 | 
						|
    Comments:
 | 
						|
        none
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub getAllSN
 | 
						|
{
 | 
						|
   
 | 
						|
    my ($class, $options) = @_;
 | 
						|
    require xCAT::Table;
 | 
						|
    # reads all nodes from the service node table
 | 
						|
    my @servicenodes;
 | 
						|
    my $servicenodetab = xCAT::Table->new('servicenode');
 | 
						|
    unless ($servicenodetab)    # no  servicenode table
 | 
						|
    {
 | 
						|
        xCAT::MsgUtils->message('I', "Unable to open servicenode table.\n");
 | 
						|
        $servicenodetab->close;
 | 
						|
        return @servicenodes;
 | 
						|
 | 
						|
    }
 | 
						|
    my @nodes = $servicenodetab->getAllNodeAttribs(['tftpserver']);
 | 
						|
    foreach my $nodes (@nodes)
 | 
						|
    {
 | 
						|
          push @servicenodes, $nodes->{node};
 | 
						|
    }
 | 
						|
    # if did not input "ALL" and there is a MN, remove it
 | 
						|
    my @newservicenodes;
 | 
						|
    if ((!defined($options)) || ($options ne "ALL")) {   
 | 
						|
       my $mname = xCAT::Utils->noderangecontainsMn(@servicenodes);
 | 
						|
       if ($mname) { # if there is a MN
 | 
						|
        foreach my $nodes (@servicenodes) {
 | 
						|
           if ($mname ne ($nodes)){
 | 
						|
              push @newservicenodes, $nodes;
 | 
						|
           }
 | 
						|
        }
 | 
						|
        $servicenodetab->close;
 | 
						|
        return @newservicenodes;  # return without the MN in the array
 | 
						|
       }
 | 
						|
    }
 | 
						|
    $servicenodetab->close;
 | 
						|
    return @servicenodes;
 | 
						|
}
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 getSNandNodes 
 | 
						|
 
 | 
						|
    Returns an hash-array of all service nodes and the nodes they service
 | 
						|
 | 
						|
    Arguments:
 | 
						|
       none 
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 getSNandNodes 
 | 
						|
 
 | 
						|
    Returns an hash-array of all service nodes and the nodes they service
 | 
						|
 | 
						|
    Arguments:
 | 
						|
       none 
 | 
						|
    Returns:
 | 
						|
	 Service Nodes and the nodes they service or empty , if none
 | 
						|
    Globals:
 | 
						|
        none
 | 
						|
    Error:
 | 
						|
        1 - error
 | 
						|
    Example:
 | 
						|
        $sn=xCAT::ServiceNodeUtils->getSNandNodes()
 | 
						|
    Comments:
 | 
						|
        none
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub getSNandNodes
 | 
						|
{
 | 
						|
 | 
						|
    require xCAT::Table;
 | 
						|
    # read all the nodes from the nodelist table
 | 
						|
    #  call get_ServiceNode to find which Service Node
 | 
						|
    # the node belongs to.
 | 
						|
    my %sn;
 | 
						|
    my @nodes;
 | 
						|
    my $nodelisttab = xCAT::Table->new('nodelist');
 | 
						|
    my $recs        = $nodelisttab->getAllEntries();
 | 
						|
    foreach (@$recs)
 | 
						|
    {
 | 
						|
        push @nodes, $_->{node};
 | 
						|
    }
 | 
						|
    $nodelisttab->close;
 | 
						|
    my $sn = xCAT::ServiceNodeUtils->get_ServiceNode(\@nodes, "xcat", "MN");
 | 
						|
    return $sn;
 | 
						|
}
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 getSNList 
 | 
						|
 
 | 
						|
	Reads the servicenode table. Will return all the enabled Service Nodes
 | 
						|
	that will setup the input Service ( e.g tftpserver,nameserver,etc)
 | 
						|
	If service is blank, then will return the list of all enabled Service
 | 
						|
	Nodes. 
 | 
						|
 | 
						|
    Arguments:
 | 
						|
       Servicename ( xcat,tftpserver,dhcpserver,conserver,etc) 
 | 
						|
       If no servicename, returns all Servicenodes
 | 
						|
       "ALL" argument means you also want the MN returned. It can be in the 
 | 
						|
       servicenode list.  If no "ALL", take out the MN if it is there. 
 | 
						|
    Returns:
 | 
						|
	  Array of service node names 
 | 
						|
    Globals:
 | 
						|
        none
 | 
						|
    Error:
 | 
						|
        1 - error  
 | 
						|
    Example:
 | 
						|
         $sn= xCAT::ServiceNodeUtils->getSNList($servicename) { blah; }
 | 
						|
         $sn= xCAT::ServiceNodeUtils->getSNList($servicename,"ALL") { blah; }
 | 
						|
         $sn= xCAT::ServiceNodeUtils->getSNList() { blah; }
 | 
						|
         $sn= xCAT::ServiceNodeUtils->getSNList("","ALL") { blah; }
 | 
						|
    Comments:
 | 
						|
        none
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub getSNList
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    my ($class, $service,$options) = @_;
 | 
						|
 | 
						|
    # reads all nodes from the service node table
 | 
						|
    my @servicenodes;
 | 
						|
    my $servicenodetab = xCAT::Table->new('servicenode', -create => 1);
 | 
						|
    unless ($servicenodetab)    # no  servicenode table
 | 
						|
    {
 | 
						|
        xCAT::MsgUtils->message('I', "Unable to open servicenode table.\n");
 | 
						|
        return ();
 | 
						|
    }
 | 
						|
    my @nodes = $servicenodetab->getAllNodeAttribs([$service]);
 | 
						|
    $servicenodetab->close;
 | 
						|
    foreach my $node (@nodes)
 | 
						|
    {
 | 
						|
        if ($service eq "")     # want all the service nodes
 | 
						|
        {
 | 
						|
            push @servicenodes, $node->{node};
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {                       # looking for a particular service
 | 
						|
            if ($node->{$service})
 | 
						|
            {                   # if null then do not add node
 | 
						|
                my $value = $node->{$service};
 | 
						|
                $value =~ tr/a-z/A-Z/;    # convert to upper
 | 
						|
                     # value 1 or yes or blank then we setup the service
 | 
						|
                if (($value == 1) || ($value eq "YES"))
 | 
						|
                {
 | 
						|
                    push @servicenodes, $node->{node};
 | 
						|
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    # if did not input "ALL" and there is a MN, remove it
 | 
						|
    my @newservicenodes;
 | 
						|
    if ((!defined($options)) || ($options ne "ALL")) {   
 | 
						|
       my $mname = xCAT::Utils->noderangecontainsMn(@servicenodes);
 | 
						|
       if ($mname) { # if there is a MN
 | 
						|
        foreach my $nodes (@servicenodes) {
 | 
						|
           if ($mname ne ($nodes)){
 | 
						|
              push @newservicenodes, $nodes;
 | 
						|
           }
 | 
						|
        }
 | 
						|
        return @newservicenodes;  # return without the MN in the array
 | 
						|
       }
 | 
						|
    }
 | 
						|
 | 
						|
    return @servicenodes;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 get_ServiceNode
 | 
						|
 | 
						|
     Will get the Service node ( name or ipaddress) as known by the Management
 | 
						|
	 Node  or Node for the input nodename or ipadress of the node 
 | 
						|
         which can be a Service Node.
 | 
						|
         If the input node is a Service Node then it's Service node
 | 
						|
         is always the Management Node.
 | 
						|
 | 
						|
     input: list of nodenames and/or node ipaddresses (array ref)
 | 
						|
			service name
 | 
						|
			"MN" or "Node"  determines if you want the Service node as known
 | 
						|
			 by the Management Node  or by the node.
 | 
						|
 | 
						|
		recognized service names: xcat,tftpserver,
 | 
						|
		nfsserver,conserver,monserver
 | 
						|
 | 
						|
        service "xcat" is used by command like xdsh that need to know the
 | 
						|
		service node that will process the command but are not tied to a
 | 
						|
		specific service like tftp
 | 
						|
 | 
						|
		Todo:  Handle  dhcpserver and nameserver from the networks table
 | 
						|
 | 
						|
	 output: A hash ref  of arrays, the key is the service node pointing to
 | 
						|
			 an array of nodes that are serviced by that service node
 | 
						|
 | 
						|
     Globals:
 | 
						|
        $::ERROR_RC
 | 
						|
     Error:
 | 
						|
         $::ERROR_RC=0 no error $::ERROR_RC=1 error
 | 
						|
 | 
						|
	 example: $sn =xCAT::ServiceNodeUtils->get_ServiceNode(\@nodes,$service,"MN");
 | 
						|
	  $sn =xCAT::ServiceNodeUtils->get_ServiceNode(\@nodes,$service,"Node");
 | 
						|
        Note: this rountine is important to hierarchical support in xCAT
 | 
						|
              and used in many places.  Any changes to the logic should be
 | 
						|
              reviewed by xCAT architecture
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub get_ServiceNode
 | 
						|
{
 | 
						|
    require xCAT::Table;
 | 
						|
    my ($class, $node, $service, $request) = @_;
 | 
						|
    my @node_list = @$node;
 | 
						|
    my $cmd;
 | 
						|
    my %snhash;
 | 
						|
    my $nodehash;
 | 
						|
    my $sn;
 | 
						|
    my $nodehmtab;
 | 
						|
    my $noderestab;
 | 
						|
    my $snattribute;
 | 
						|
    my $oshash;
 | 
						|
    my $nodetab;
 | 
						|
    $::ERROR_RC = 0;
 | 
						|
 | 
						|
    # determine if the request is for the service node as known by the MN
 | 
						|
    # or the node
 | 
						|
 | 
						|
    if ($request eq "MN")
 | 
						|
    {
 | 
						|
        $snattribute = "servicenode";
 | 
						|
 | 
						|
    }
 | 
						|
    else    # Node
 | 
						|
    {
 | 
						|
        $snattribute = "xcatmaster";
 | 
						|
    }
 | 
						|
    # get site.master this will be the default
 | 
						|
    my $master = xCAT::TableUtils->get_site_Master();  
 | 
						|
    $noderestab = xCAT::Table->new('noderes');
 | 
						|
 | 
						|
    unless ($noderestab)    # no noderes table, use default site.master
 | 
						|
    {
 | 
						|
        xCAT::MsgUtils->message('I',
 | 
						|
                         "Unable to open noderes table. Using site->Master.\n");
 | 
						|
 | 
						|
        if ($master)        # use site Master value
 | 
						|
        {
 | 
						|
				
 | 
						|
            foreach my $node (@node_list)
 | 
						|
            {               
 | 
						|
					push @{$snhash{$master}}, $node;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            xCAT::MsgUtils->message('E', "Unable to read site Master value.\n");
 | 
						|
            $::ERROR_RC = 1;
 | 
						|
        }
 | 
						|
 | 
						|
        return \%snhash;
 | 
						|
    }
 | 
						|
 | 
						|
    if ($service eq "xcat")
 | 
						|
    {    # find all service nodes for the nodes in the list
 | 
						|
 | 
						|
        $nodehash = $noderestab->getNodesAttribs(\@node_list, [$snattribute]);
 | 
						|
 | 
						|
 | 
						|
        foreach my $node (@node_list)
 | 
						|
        {
 | 
						|
            foreach my $rec (@{$nodehash->{$node}})
 | 
						|
            {
 | 
						|
                if ($rec and $rec->{$snattribute}) # use noderes.servicenode
 | 
						|
                {
 | 
						|
                    my $key = $rec->{$snattribute};
 | 
						|
                    push @{$snhash{$key}}, $node;
 | 
						|
                }
 | 
						|
                else  # use site.master
 | 
						|
                {    
 | 
						|
  		  push @{$snhash{$master}}, $node;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        $noderestab->close;
 | 
						|
        return \%snhash;
 | 
						|
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        if (
 | 
						|
            ($service eq "tftpserver")    # all from noderes table
 | 
						|
            || ($service eq "nfsserver") || ($service eq "monserver")
 | 
						|
          )
 | 
						|
        {
 | 
						|
            $nodehash =
 | 
						|
              $noderestab->getNodesAttribs(\@node_list,
 | 
						|
                                           [$service, $snattribute]);
 | 
						|
            foreach my $node (@node_list)
 | 
						|
            {
 | 
						|
                foreach my $rec (@{$nodehash->{$node}})
 | 
						|
                {
 | 
						|
                    if ($rec and $rec->{$service})
 | 
						|
                    {
 | 
						|
 | 
						|
                        # see if both  MN and Node address in attribute
 | 
						|
                        my ($msattr, $nodeattr) = split ':', $rec->{$service};
 | 
						|
                        my $key = $msattr;
 | 
						|
                        if ($request eq "Node")
 | 
						|
                        {
 | 
						|
                            if ($nodeattr)    # override with Node, if it exists
 | 
						|
                            {
 | 
						|
                                $key = $nodeattr;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        push @{$snhash{$key}}, $node;
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        if ($rec and $rec->{$snattribute})    # if it exists
 | 
						|
                        {
 | 
						|
                            my $key = $rec->{$snattribute};
 | 
						|
                            push @{$snhash{$key}}, $node;
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {                                     # use site.master
 | 
						|
                            push @{$snhash{$master}}, $node;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            $noderestab->close;
 | 
						|
            return \%snhash;
 | 
						|
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if ($service eq "conserver")
 | 
						|
            {
 | 
						|
 | 
						|
                # read the nodehm table
 | 
						|
                $nodehmtab = xCAT::Table->new('nodehm');
 | 
						|
                unless ($nodehmtab)    # no nodehm table
 | 
						|
                {
 | 
						|
                    xCAT::MsgUtils->message('I',
 | 
						|
                                            "Unable to open nodehm table.\n");
 | 
						|
 | 
						|
                    # use servicenode
 | 
						|
                    $nodehash =
 | 
						|
                      $noderestab->getNodesAttribs(\@node_list, [$snattribute]);
 | 
						|
                    foreach my $node (@node_list)
 | 
						|
                    {
 | 
						|
                        foreach my $rec (@{$nodehash->{$node}})
 | 
						|
                        {
 | 
						|
                            if ($rec and $rec->{$snattribute})
 | 
						|
                            {
 | 
						|
                                my $key = $rec->{$snattribute};
 | 
						|
                                push @{$snhash{$key}}, $node;
 | 
						|
                            }
 | 
						|
                            else
 | 
						|
                            {    # use site.master
 | 
						|
                                push @{$snhash{$master}}, $node;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    $noderestab->close;
 | 
						|
                    return \%snhash;
 | 
						|
                }
 | 
						|
 | 
						|
                # can read the nodehm table
 | 
						|
                $nodehash =
 | 
						|
                  $nodehmtab->getNodesAttribs(\@node_list, ['conserver']);
 | 
						|
                foreach my $node (@node_list)
 | 
						|
                {
 | 
						|
                    foreach my $rec (@{$nodehash->{$node}})
 | 
						|
                    {
 | 
						|
                        if ($rec and $rec->{'conserver'})
 | 
						|
                        {
 | 
						|
 | 
						|
                            # see if both  MN and Node address in attribute
 | 
						|
                            my ($msattr, $nodeattr) = split ':',
 | 
						|
                              $rec->{'conserver'};
 | 
						|
                            my $key = $msattr;
 | 
						|
                            if ($request eq "Node")
 | 
						|
                            {
 | 
						|
                                if ($nodeattr
 | 
						|
                                  )    # override with Node, if it exists
 | 
						|
                                {
 | 
						|
                                    $key = $nodeattr;
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            push @{$snhash{$key}}, $node;
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {              # use service node for this node
 | 
						|
                            $sn =
 | 
						|
                              $noderestab->getNodeAttribs($node,
 | 
						|
                                                          [$snattribute]);
 | 
						|
                            if ($sn and $sn->{$snattribute})
 | 
						|
                            {
 | 
						|
                                my $key = $sn->{$snattribute};
 | 
						|
                                push @{$snhash{$key}}, $node;
 | 
						|
                            }
 | 
						|
                            else
 | 
						|
                            {          # no service node use master
 | 
						|
                                push @{$snhash{$master}}, $node;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                $noderestab->close;
 | 
						|
                $nodehmtab->close;
 | 
						|
                return \%snhash;
 | 
						|
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                xCAT::MsgUtils->message('E',
 | 
						|
                                        "Invalid service=$service input.\n");
 | 
						|
                $::ERROR_RC = 1;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return \%snhash;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3 getSNformattedhash
 | 
						|
 | 
						|
     Will call get_ServiceNode to  get the Service node ( name or ipaddress)
 | 
						|
	 as known by the Management
 | 
						|
	 Server or Node for the input nodename or ipadress of the node
 | 
						|
	 It will then format the output into a single servicenode key with values
 | 
						|
	 the list of nodes service by that service node.  This routine will 
 | 
						|
	 break up pools of service nodes into individual node in the hash unlike
 | 
						|
	 get_ServiceNode which leaves the pool as the key.
 | 
						|
 | 
						|
	 input:  Same as get_ServiceNode to call get_ServiceNode
 | 
						|
			list of nodenames and/or node ipaddresses (array ref)
 | 
						|
			service name
 | 
						|
			"MN" or "Node"  determines if you want the Service node as known
 | 
						|
			 by the Management Node  or by the node.
 | 
						|
 | 
						|
		recognized service names: xcat,tftpserver,
 | 
						|
		nfsserver,conserver,monserver
 | 
						|
 | 
						|
        service "xcat" is used by command like xdsh that need to know the
 | 
						|
		service node that will process the command but are not tied to a
 | 
						|
		specific service like tftp
 | 
						|
 | 
						|
 | 
						|
	 output: A hash ref  of arrays, the key is a single service node 
 | 
						|
	          pointing to
 | 
						|
			 a list of nodes that are serviced by that service node
 | 
						|
	        'rra000-m'=>['blade01', 'testnode']
 | 
						|
	        'sn1'=>['blade01', 'testnode']
 | 
						|
	        'sn2'=>['blade01']
 | 
						|
	        'sn3'=>['testnode']
 | 
						|
 | 
						|
     Globals:
 | 
						|
        $::ERROR_RC
 | 
						|
     Error:
 | 
						|
         $::ERROR_RC=0 no error $::ERROR_RC=1 error
 | 
						|
 | 
						|
	 example: $sn =xCAT::ServiceNodeUtils->getSNformattedhash(\@nodes,$service,"MN", $type);
 | 
						|
	  $sn =xCAT::ServiceNodeUtils->getSNformattedhash(\@nodes,$service,"Node", "primary");
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub getSNformattedhash
 | 
						|
{
 | 
						|
    my ($class, $node, $service, $request, $btype) = @_;
 | 
						|
    my @node_list = @$node;
 | 
						|
    my $cmd;
 | 
						|
    my %newsnhash;
 | 
						|
 | 
						|
	my $type="";
 | 
						|
	if ($btype) {
 | 
						|
		$type=$btype;
 | 
						|
	}
 | 
						|
 | 
						|
	# get the values of either the servicenode or xcatmaster attributes
 | 
						|
    my $sn = xCAT::ServiceNodeUtils->get_ServiceNode(\@node_list, $service, $request);
 | 
						|
 | 
						|
    # get the keys which are the service nodes and break apart any pool lists
 | 
						|
    # format into individual service node keys pointing to node lists
 | 
						|
	if ($sn)
 | 
						|
	{
 | 
						|
        foreach my $snkey (keys %$sn)
 | 
						|
        {
 | 
						|
			# split the key if pool of service nodes
 | 
						|
			push my @tmpnodes, $sn->{$snkey};
 | 
						|
			my @nodes;
 | 
						|
			for my $i (0 .. $#tmpnodes) {
 | 
						|
				for my $j ( 0 .. $#{$tmpnodes[$i]}) {
 | 
						|
					my $check=$tmpnodes[$i][$j];
 | 
						|
					push @nodes,$check; 
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			# for SN backup we might only want the primary or backup
 | 
						|
			my @servicenodes;
 | 
						|
			my ($primary, $backup) = split /,/, $snkey;
 | 
						|
			if (($primary) && ($type eq "primary")) {
 | 
						|
				push @servicenodes, $primary;
 | 
						|
			} elsif (($backup) && ($type eq "backup")) {
 | 
						|
				push @servicenodes, $backup;
 | 
						|
			} else {
 | 
						|
				@servicenodes = split /,/, $snkey;
 | 
						|
			}
 | 
						|
 | 
						|
			# now build new hash of individual service nodes
 | 
						|
			foreach my $newsnkey (@servicenodes) {
 | 
						|
				push @{$newsnhash{$newsnkey}}, @nodes;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
    return \%newsnhash;
 | 
						|
}
 | 
						|
 | 
						|
#----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3  getAIXSNinterfaces
 | 
						|
 | 
						|
	Get a list of ip addresses for each service node in a list
 | 
						|
 | 
						|
	Arguments:
 | 
						|
		list of service nodes
 | 
						|
	Returns:
 | 
						|
		hash of ips for each service node
 | 
						|
	Globals:
 | 
						|
		none
 | 
						|
	Error:
 | 
						|
		none
 | 
						|
	Example:
 | 
						|
		my $sni = xCAT::ServiceNodeUtils->getAIXSNinterfaces(\@servlist, $callback, $subreq);
 | 
						|
 | 
						|
	Comments:
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub getAIXSNinterfaces
 | 
						|
{
 | 
						|
    my ($class, $list, $callback, $sub_req) = @_;
 | 
						|
 | 
						|
    my @snlist = @$list;
 | 
						|
    my %SNinterfaces;
 | 
						|
 | 
						|
    # get all the possible IPs for the node I'm running on
 | 
						|
    my $ifcmd = "/usr/sbin/ifconfig -a | grep 'inet ' ";
 | 
						|
    foreach my $sn (@snlist)
 | 
						|
    {
 | 
						|
        my $SNIP;
 | 
						|
        my $out = xCAT::InstUtils->xcmd($callback, $sub_req, "xdsh", $sn, $ifcmd, 0);
 | 
						|
        if ($::RUNCMD_RC != 0)
 | 
						|
        {
 | 
						|
			my $rsp;
 | 
						|
			push @{$rsp->{data}}, "Could not get IP addresses from service node $sn.\n";
 | 
						|
			xCAT::MsgUtils->message("E", $rsp, $callback);
 | 
						|
            next;
 | 
						|
        }
 | 
						|
 | 
						|
		my @result;
 | 
						|
		foreach my $line ( split(/\n/, $out)) {
 | 
						|
			$line =~ s/$sn:\s+//;
 | 
						|
			push(@result, $line);
 | 
						|
		}
 | 
						|
 | 
						|
		foreach my $int (@result) {
 | 
						|
			my ($inet, $SNIP, $str) = split(" ", $int);
 | 
						|
			chomp $SNIP;
 | 
						|
			$SNIP =~ s/\/.*//; # ipv6 address 4000::99/64
 | 
						|
			$SNIP =~ s/\%.*//; # ipv6 address ::1%1/128
 | 
						|
            push(@{$SNinterfaces{$sn}}, $SNIP);
 | 
						|
        }
 | 
						|
    } # end foreach SN
 | 
						|
   	return \%SNinterfaces;
 | 
						|
}
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3  
 | 
						|
 
 | 
						|
    getSNandCPnodes - Take an array of nodes and returns 
 | 
						|
    an array of the service 
 | 
						|
    nodes and an array of the computenode . 
 | 
						|
 | 
						|
    Arguments:
 | 
						|
       none 
 | 
						|
    Returns:
 | 
						|
		array of Service Nodes and/or array of compute nodesarray of compute nodes       empty array, if none
 | 
						|
    Globals:
 | 
						|
        none
 | 
						|
    Error:
 | 
						|
        1 - error
 | 
						|
    Example:
 | 
						|
         xCAT::ServiceNodeUtils->getSNandCPnodes(\@nodes,\@SN,\@CN);
 | 
						|
    Comments:
 | 
						|
        none
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-----------------------------------------------------------------------------
 | 
						|
sub getSNandCPnodes 
 | 
						|
{
 | 
						|
   
 | 
						|
    my ($class, $nodes,$sn,$cn) = @_; 
 | 
						|
    my @nodelist = @$nodes;
 | 
						|
    # get the list of all Service nodes
 | 
						|
    my @allSN=xCAT::ServiceNodeUtils->getAllSN;
 | 
						|
    foreach my $node (@nodelist) {
 | 
						|
      if (grep(/^$node$/, @allSN)) { # it is a SN
 | 
						|
         push (@$sn,$node);
 | 
						|
      } else {  # a CN
 | 
						|
         push (@$cn,$node);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return ; 
 | 
						|
}
 | 
						|
1;
 |