mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-04 05:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			290 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
#!/usr/bin/env perl
 | 
						|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
#-------------------------------------------------------
 | 
						|
package xCAT::ExtTab;
 | 
						|
 | 
						|
BEGIN
 | 
						|
{
 | 
						|
    $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#
 | 
						|
#NO xCAT perl library routines should be used in this begin block
 | 
						|
#(i.e. MsgUtils,Utils, etc)
 | 
						|
#
 | 
						|
#use lib "$::XCATROOT/lib/perl";
 | 
						|
 | 
						|
use File::Path;
 | 
						|
%ext_tabspec = ();
 | 
						|
%ext_defspec = ();
 | 
						|
 | 
						|
 | 
						|
# loads user defined table spec. They are stored under /opt/xcat/lib/perl/xCAT_schema directory
 | 
						|
my $path = "$::XCATROOT/lib/perl/xCAT_schema";
 | 
						|
my $filelist;    # no specific files
 | 
						|
my @extSchema = &get_filelist($path, $filelist, "pm");
 | 
						|
 | 
						|
#   print "\nextSchema=@extSchema\n";
 | 
						|
 | 
						|
foreach (@extSchema) {
 | 
						|
    /.*\/([^\/]*).pm$/;
 | 
						|
    my $file    = $_;
 | 
						|
    my $modname = $1;
 | 
						|
    no strict 'refs';
 | 
						|
    my $warning;
 | 
						|
 | 
						|
    # `logger -t xcat processing $_`;
 | 
						|
    eval { require($_) };
 | 
						|
    if ($@) {
 | 
						|
        $warning = "Warning: The user defined database table schema file $file cannot be located or has compiling errors.\n";
 | 
						|
        print $warning;
 | 
						|
        `logger -p local4.warning -t xcat $warning`;
 | 
						|
        next;
 | 
						|
    }
 | 
						|
    if (${ "xCAT_schema::" . "$modname" . "::" }{tabspec}) {
 | 
						|
        my %tabspec = %{ ${ "xCAT_schema::" . "$modname" . "::" }{tabspec} };
 | 
						|
        foreach my $tabname (keys(%tabspec)) {
 | 
						|
            if (exists($ext_tabspec{$tabname})) {
 | 
						|
                $warning = "Warning: File $file: the table name $tabname is used by other applications. Please rename the table.\n";
 | 
						|
                print $warning;
 | 
						|
                `logger -p local4.warning -t xcat $warning`;
 | 
						|
            } else {
 | 
						|
                $ext_tabspec{$tabname} = $tabspec{$tabname};
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        $warning = "\n  Warning: Cannot find \%tabspec variable in the user defined database table schema file $file\n";
 | 
						|
        print $warning;
 | 
						|
        `logger -p local4.warning -t xcat $warning`;
 | 
						|
    }
 | 
						|
 | 
						|
    #get the defspec from each file and merge them into %ext_defspec
 | 
						|
    if (${ "xCAT_schema::" . "$modname" . "::" }{defspec}) {
 | 
						|
        my %defspec = %{ ${ "xCAT_schema::" . "$modname" . "::" }{defspec} };
 | 
						|
        foreach my $objname (keys(%defspec)) {
 | 
						|
            if (exists($defspec{$objname}->{'attrs'})) {
 | 
						|
                if (exists($ext_defspec{$objname})) {
 | 
						|
 | 
						|
                    #print "insert\n";
 | 
						|
                    my @attr_new = @{ $defspec{$objname}->{'attrs'} };
 | 
						|
                    my @attr     = @{ $ext_defspec{$objname}->{'attrs'} };
 | 
						|
                    my %tmp_hash = ();
 | 
						|
                    foreach my $orig (@attr) {
 | 
						|
                        my $attrname = $orig->{attr_name};
 | 
						|
                        $tmp_hash{$attrname} = 1;
 | 
						|
                    }
 | 
						|
                    foreach my $h (@attr_new) {
 | 
						|
                        my $attrname = $h->{attr_name};
 | 
						|
                        if (exists($tmp_hash{$attrname})) {
 | 
						|
                            $warning = "  Warning: Conflict when adding user defined defspec from file $file. Attribute name $attrname is already defined in object $objname.  \n";
 | 
						|
                            print $warning;
 | 
						|
                            `logger  -p local4.warning  -t xcat $warning`;
 | 
						|
                        } else {
 | 
						|
 | 
						|
                            #print "\ngot here objname=$objname, attrname=" . $h->{attr_name} . "\n";
 | 
						|
                            push(@{ $ext_defspec{$objname}->{'attrs'} }, $h);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                } else {
 | 
						|
 | 
						|
                    #print "\ngot here objname=$objname, file=$file\n";
 | 
						|
                    $ext_defspec{$objname} = $defspec{$objname};
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
}    #foreach
 | 
						|
 | 
						|
#print out the defspec
 | 
						|
#print "\nexternal defspec:\n";
 | 
						|
#foreach(%ext_defspec) {
 | 
						|
#    print "  $_:\n";
 | 
						|
#    my @attr=@{$ext_defspec{$_}->{'attrs'}};
 | 
						|
#    foreach my $h (@attr) {
 | 
						|
#	print "    " . $h->{attr_name} . "\n";
 | 
						|
#    }
 | 
						|
#}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head1 xCAT::ExtTab
 | 
						|
 | 
						|
    Handles user defined database tables.
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  updateTables
 | 
						|
 | 
						|
     It is called by xcatd to generate the user-defined tables
 | 
						|
  if they do not exist, it also updates the tables if there is
 | 
						|
  a schema change.
 | 
						|
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
sub updateTables
 | 
						|
{
 | 
						|
    #print "\nupdateTables\n";
 | 
						|
    #print "\n";
 | 
						|
    foreach (keys %ext_tabspec) {
 | 
						|
        my $table = xCAT::Table->new($_, -create => 1);
 | 
						|
        my $rc = $table->updateschema();
 | 
						|
        $table->close();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#--------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3
 | 
						|
    Note this is a copy of the one in Table.pm but we cannot use any of the
 | 
						|
    xCAT perl libraries in this routine,since the function was done in the
 | 
						|
    Begin block.
 | 
						|
    Description: get_filelist
 | 
						|
 | 
						|
    Arguments:
 | 
						|
             directory,filelist,type
 | 
						|
    Returns:
 | 
						|
            The list of sql files to be processed which consists of all the
 | 
						|
			files with <name>.sql  and <name>_<databasename>.sql
 | 
						|
		        or 	
 | 
						|
			files with <name>.pm  and <name>_<databasename>.pm
 | 
						|
    Globals:
 | 
						|
 | 
						|
    Error:
 | 
						|
 | 
						|
    Example:
 | 
						|
	my @filelist =get_filelist($directory,$filelist,$type);
 | 
						|
            where type = "sql" or "pm"
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#--------------------------------------------------------------------------------
 | 
						|
 | 
						|
sub get_filelist
 | 
						|
 | 
						|
{
 | 
						|
    use File::Basename;
 | 
						|
    my $directory = shift;
 | 
						|
    my $files     = shift;
 | 
						|
    my $ext       = shift;
 | 
						|
    my $dbname    = "sqlite";
 | 
						|
    my $xcatcfg   = get_xcatcfg();
 | 
						|
 | 
						|
    if ($xcatcfg =~ /^DB2:/)
 | 
						|
    {
 | 
						|
        $dbname = "db2";
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        if ($xcatcfg =~ /^mysql:/)
 | 
						|
        {
 | 
						|
            $dbname = "mysql";
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if ($xcatcfg =~ /^Pg:/)
 | 
						|
            {
 | 
						|
                $dbname = "pgsql";
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    $directory .= "/";
 | 
						|
 | 
						|
    my @filelist = ();
 | 
						|
 | 
						|
    my @list = glob($directory . "*.$ext");    # all files
 | 
						|
    foreach my $file (@list)
 | 
						|
    {
 | 
						|
        my $filename = basename($file);        # strip filename
 | 
						|
        my ($name,    $ext1) = split '\.', $filename;
 | 
						|
        my ($tmpname, $ext2) = split '\_', $name;
 | 
						|
        if ($ext2 eq $dbname)                  # matches the database
 | 
						|
        {
 | 
						|
            push @filelist, $file;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if ($ext2 eq "")                   # no database designated
 | 
						|
            {
 | 
						|
                push @filelist, $file;
 | 
						|
            } else {    # if not one of the databases, they just have _ in
 | 
						|
                        # the file name
 | 
						|
                if ($ext2 ne "db2" && $ext2 ne "mysql" && $ext2 ne "pgsql" && $ext2 ne "sqlite") {
 | 
						|
                    push @filelist, $file;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        $ext2 = "";
 | 
						|
        $ext1 = "";
 | 
						|
    }
 | 
						|
    return @filelist;
 | 
						|
}
 | 
						|
 | 
						|
#--------------------------------------------------------------------------
 | 
						|
 | 
						|
=head3
 | 
						|
 | 
						|
    Note this is a copy of the one in Table.pm but we cannot use any of the
 | 
						|
    xCAT perl libraries in this routine,since the function was done in the
 | 
						|
 | 
						|
    Description: get_xcatcfg
 | 
						|
 | 
						|
    Arguments:
 | 
						|
              none
 | 
						|
    Returns:
 | 
						|
              the database name from /etc/xcat/cfgloc or sqlite
 | 
						|
    Globals:
 | 
						|
 | 
						|
    Error:
 | 
						|
 | 
						|
    Example:
 | 
						|
	my $xcatcfg =get_xcatcfg();
 | 
						|
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#--------------------------------------------------------------------------------
 | 
						|
 | 
						|
sub get_xcatcfg
 | 
						|
{
 | 
						|
    my $xcatcfg = (defined $ENV{'XCATCFG'} ? $ENV{'XCATCFG'} : '');
 | 
						|
    unless ($xcatcfg) {
 | 
						|
        if (-r "/etc/xcat/cfgloc") {
 | 
						|
            my $cfgl;
 | 
						|
            open($cfgl, "<", "/etc/xcat/cfgloc");
 | 
						|
            $xcatcfg = <$cfgl>;
 | 
						|
            close($cfgl);
 | 
						|
            chomp($xcatcfg);
 | 
						|
            $ENV{'XCATCFG'} = $xcatcfg; #Store it in env to avoid many file reads
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if ($xcatcfg =~ /^$/)
 | 
						|
    {
 | 
						|
        if (-d "/opt/xcat/cfg")
 | 
						|
        {
 | 
						|
            $xcatcfg = "SQLite:/opt/xcat/cfg";
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if (-d "/etc/xcat")
 | 
						|
            {
 | 
						|
                $xcatcfg = "SQLite:/etc/xcat";
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    unless ($xcatcfg =~ /:/)
 | 
						|
    {
 | 
						|
        $xcatcfg = "SQLite:" . $xcatcfg;
 | 
						|
    }
 | 
						|
    return $xcatcfg;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
1;
 |