xcat-core/perl-xCAT/xCAT/ExtTab.pm
2012-04-12 05:26:55 +00:00

279 lines
7.3 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;