added support for user-defined database tables, phase 1
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2590 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		
							
								
								
									
										113
									
								
								perl-xCAT/xCAT/ExtTab.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								perl-xCAT/xCAT/ExtTab.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										91
									
								
								xCAT-server/lib/xcat/schema/samples/Sample.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								xCAT-server/lib/xcat/schema/samples/Sample.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
|  | ||||
|  | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user