diff --git a/perl-xCAT/xCAT/ExtTab.pm b/perl-xCAT/xCAT/ExtTab.pm new file mode 100644 index 000000000..9b63afe09 --- /dev/null +++ b/perl-xCAT/xCAT/ExtTab.pm @@ -0,0 +1,113 @@ +#!/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'; +} +use lib "$::XCATROOT/lib/perl"; + +use xCAT::MsgUtils; +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 @extSchema=glob($path."/*.pm"); + # print "\nextSchema=@extSchema\n"; + +foreach (@extSchema) { + /.*\/([^\/]*).pm$/; + my $file=$_; + my $modname = $1; + no strict 'refs'; + eval {require($_)}; + if ($@) { + xCAT::MsgUtils->message('ES',"\n Warning: The user defined database table schema file $file cannot be located or has compiling errors.\n"); + next; + } + if (${"xCAT_schema::" . "$modname" . "::"}{tabspec}) { + my %tabspec=%{${"xCAT_schema::" . "$modname" . "::"}{tabspec}}; + foreach my $tabname (keys(%tabspec)) { + $ext_tabspec{$tabname}=$tabspec{$tabname}; + } + } else { + xCAT::MsgUtils->message('ES', "\n Warning: Cannot find \%tabspec variable in the user defined database table schema file $file\n"); + } + + #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})) { + xCAT::MsgUtils->message('ES', "\n Warning: Conflict when adding user defined defspec from file $file. Attribute name $attrname is already defined in object $objname. \n"); + } 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 + Schmea change. + + +=cut +#------------------------------------------------------- + +sub updateTables +{ + #print "\nupdateTables\n"; + foreach (keys %ext_tabspec) { + my $table= xCAT::Table->new($_,-create=>1,-autocommit=>1); + } +} + +1; diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 4123945bc..7ed5c0c5c 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -1,5 +1,11 @@ # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html package xCAT::Schema; +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; +} +use lib "$::XCATROOT/lib/perl"; +use xCAT::ExtTab; # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # @@ -578,6 +584,18 @@ performance => { ); # end of tabspec definition + +################################################### +# adding user defined external tables +################################################## +foreach my $tabname (keys(%xCAT::ExtTab::ext_tabspec)) { + $tabspec{$tabname}=$xCAT::ExtTab::ext_tabspec{$tabname}; +} + + + + + #################################################### # # Data abstraction definitions @@ -623,7 +641,7 @@ performance => { #site => { attrs => [], attrhash => {}, objkey => 'sitename' }, policy => { attrs => [], attrhash => {}, objkey => 'priority' }, monitoring => { attrs => [], attrhash => {}, objkey => 'name' }, - notification => { attrs => [], attrhash => {}, objkey => 'filename' } + notification => { attrs => [], attrhash => {}, objkey => 'filename' }, ); @@ -1410,28 +1428,46 @@ push(@{$defspec{group}->{'attrs'}}, @nodeattrs); }, ); -######################### -# performance table # -######################### -@{$defspec{performance}->{'attrs'}} = ( - {attr_name => 'timestamp', - tabentry => 'performance.timestamp', - access_tabentry => 'performance.timestamp=attr:timestamp', - }, - {attr_name => 'node', - tabentry => 'performance.node', - access_tabentry => 'performance.timestamp=attr:timestamp', - }, - {attr_name => 'attrname', - tabentry => 'performance.netname', - access_tabentry => 'performance.timestamp=attr:timestamp', - }, - {attr_name => 'attrvalue', - tabentry => 'performance.attrvalue', - access_tabentry => 'performance.timestamp=attr:timestamp', - }, - ); + + +################################################### +# adding user defined external defspec +################################################## +foreach my $objname (keys(%xCAT::ExtTab::ext_defspec)) { + if (exists($xCAT::ExtTab::ext_defspec{$objname}->{'attrs'})) { + if (exists($defspec{$objname})) { + my @extattr=@{$xCAT::ExtTab::ext_defspec{$objname}->{'attrs'}}; + my @attr=@{$defspec{$objname}->{'attrs'}}; + my %tmp_hash=(); + foreach my $orig (@attr) { + my $attrname=$orig->{attr_name}; + $tmp_hash{$attrname}=1; + } + foreach(@extattr) { + my $attrname=$_->{attr_name}; + if (exists($tmp_hash{$attrname})) { + xCAT::MsgUtils->message('ES', "\n Warning: Conflict when adding user defined defspec. Attribute name $attrname is already defined in object $objname. \n"); + } else { + push(@{$defspec{$objname}->{'attrs'}}, $_); + } + } + } else { + $defspec{$objname}=$xCAT::ExtTab::ext_defspec{$objname}; + } + } +} + + +#print "\ndefspec:\n"; +#foreach(%xCAT::Schema::defspec) { +# print " $_:\n"; +# my @attr=@{$xCAT::Schema::defspec{$_}->{'attrs'}}; +# foreach my $h (@attr) { +# print " " . $h->{attr_name} . "\n"; +# } +#} + # Build a corresponding hash for the attribute names to make # definition access easier diff --git a/xCAT-server/lib/xcat/schema/samples/Sample.pm b/xCAT-server/lib/xcat/schema/samples/Sample.pm new file mode 100644 index 000000000..97601a18d --- /dev/null +++ b/xCAT-server/lib/xcat/schema/samples/Sample.pm @@ -0,0 +1,91 @@ +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT_schema::Sample; + +################################################################################# +# This is a sample code that contains the user defined user database schema defination. +# Here is a list of things you can do to add DB tables to xCAT database. +# 1 copy this file to /opt/xcat/lib/perl/xCAT_schema directory, rename it. +# 2 change the word Sample above to be the same as the file name. +# 3 Do NOT change the variable name "%tabspec". +# 4 lljob and llnode are the table names. +# jobid, status, node, jobstatus are the column names. Change them to your like. +# Each table must have a 'disable' column. +# 5 change the keys +# 6 change the table descriptions and column descriptions to your like. +# 7 restart the the xcatd, the tables will be automatically generated. +# 8 do above steps on all the service nodes. +# +############################################################################### +%tabspec = ( + lljob => { + cols => [qw(jobid status disable)], #do not change 'disable, it is required by xCAT + keys => [qw(jobid)], + table_desc => 'Stores jobs.', + descriptions => { + jobid => 'The job id.', + status => 'The status of the job.', + disable => "Set to 'yes' or '1' to comment out this row.", + }, + }, + llnode => { + cols => [qw(node jobid jobstatus disable)], + keys => [qw(node)], + table_desc => 'Stores the node status.', + descriptions => { + node=> 'The node.', + jobid => 'The job that runs on the node.', + jobstatus => 'The status of the job on the node.', + disable => "Set to 'yes' or '1' to comment out this row.", + }, + }, +); # end of tabspec definition + + + + + + + +################################################################## +# The following %defspec is OPTIONAL. You only need to define it +# if you want your tables to work with xCAT object abstraction layer +# commands such as lsdef, mkdef, chdef and rmdef. +# +# Note: The xCAT database accessting commands such as +# tabdump, chtab, gettab, nodels, nodeadd, nodech, etc. +# still work without it. +################################################################## + +%defspec = ( + job => { attrs => [], attrhash => {}, objkey => 'jobid' }, #create a new object called 'job', +); + +#define the attribtues in the 'job' object using the lljob talbe columns. +@{$defspec{job}->{'attrs'}} = +( + { attr_name => 'jobid', + tabentry => 'lljob.jobid', + access_tabentry => 'lljob.jobid=attr:jobid', + }, + { attr_name => 'status', + tabentry => 'lljob.status', + access_tabentry => 'lljob.jobid=attr:jobid', + }, +); + +#object 'node' already defined in /opt/xcat/lib/perl/xCAT/Schema.pm. +#Here we just add jobid and jobstatus attributes to the node object +@{$defspec{node}->{'attrs'}} = +( + { attr_name => 'jobid', + tabentry => 'llnode.jobid', + access_tabentry => 'llnode.node=attr:node', + }, + { attr_name => 'jobstatus', + tabentry => 'llnode.jobstatus', + access_tabentry => 'llnode.node=attr:node', + }, +); +1; + + diff --git a/xCAT-server/sbin/xcatd b/xCAT-server/sbin/xcatd index eb6d8491b..998911f60 100755 --- a/xCAT-server/sbin/xcatd +++ b/xCAT-server/sbin/xcatd @@ -52,6 +52,7 @@ if ($^O =~ /^linux/i) { $XML::Simple::PREFERRED_PARSER='XML::Parser'; } use xCAT::Table; +use xCAT::ExtTab; use Data::Dumper; use Getopt::Long; use Sys::Syslog qw(:DEFAULT setlogsock); @@ -120,6 +121,14 @@ $SIG{PIPE} = sub { confess "SIGPIPE $$progname encountered a broken pipe (probably Ctrl-C by client)" }; $progname = \$0; + + +#create the user defined external database tables if they do not exist. +#update the tables if there are schema changes. +if (xCAT::Utils->isMN()) { + xCAT::ExtTab->updateTables(); +} + sub daemonize { chdir('/'); umask 0022; diff --git a/xCAT-server/xCAT-server.spec b/xCAT-server/xCAT-server.spec index e2528d3b0..cc80d154f 100644 --- a/xCAT-server/xCAT-server.spec +++ b/xCAT-server/xCAT-server.spec @@ -47,7 +47,7 @@ mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin mkdir -p $RPM_BUILD_ROOT/opt/xcat/xdsh/Context mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_monitoring/samples mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_monitoring/pcp - +mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema/samples %ifos linux cp -a share/xcat/install/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/install/ @@ -108,6 +108,14 @@ chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_monitoring/samples/* chmod 755 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_monitoring/pcp chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_monitoring/pcp/* + +cp -r lib/xcat/schema/* $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema +chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema/* + +chmod 755 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema/samples +chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema/samples/* + + cp lib/xcat/shfunctions $RPM_BUILD_ROOT/%{prefix}/lib chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/shfunctions mkdir -p $RPM_BUILD_ROOT/etc/init.d