xcat-core/xCAT-server/lib/xcat/plugins/notification.pm
2008-06-03 14:56:33 +00:00

291 lines
7.9 KiB
Perl

#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::notification;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::Table;
use xCAT::NotifHandler;
1;
#-------------------------------------------------------------------------------
=head1 xCAT_plugin:notification
=head2 Package Description
xCAT notification plugini module. This mondule allows users to register and
unregister for the xCAT database table changes.
=cut
#-------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
=head3 handled_commands
It returns a list of commands handled by this plugin.
Arguments:
none
Returns:
a list of commands.
=cut
#-------------------------------------------------------------------------------
sub handled_commands {
return {
regnotif => "notification",
unregnotif => "notification",
refnotif => "notification",
lsnotif => "notification",
enablenotif => "notification",
disablenotif => "notification",
}
}
#--------------------------------------------------------------------------------
=head3 process_request
It processes the monitoring control commands.
Arguments:
request -- a hash table which contains the command name.
callback -- a callback pointer to return the response to.
args -- a list of arguments that come with the command.
Returns:
0 for success. The output is returned through the callback pointer.
1. for unsuccess. The error messages are returns through the callback pointer.
=cut
#-------------------------------------------------------------------------------
sub process_request {
use Getopt::Long;
# options can be bundled up like -vV
Getopt::Long::Configure("bundling") ;
$Getopt::Long::ignorecase=0;
my $request = shift;
my $callback = shift;
my $command = $request->{command}->[0];
my $args=$request->{arg};
if ($command eq "regnotif") {
my ($ret, $msg) = regNotification($args, $callback);
if ($msg) {
my %rsp=();
$rsp->{dara}->[0]= $msg;
$callback->($rsp);
}
return $ret;
}
elsif ($command eq "unregnotif") {
my ($ret, $msg) = unregNotification($args, $callback);
if ($msg) {
my %rsp=();
$rsp->{data}->[0]= $msg;
$callback->($rsp);
}
return $ret;
}
else {
my %rsp=();
$rsp->{data}->[0]= "unsupported command: $command.";
$callback->($rsp);
return 1;
}
}
#--------------------------------------------------------------------------------
=head3 regNotification
It registers a notification routine or a command which
will be called when there are changes in the data base tables
that the routine/command is interested in.
Arguments:
args - The format of the args is:
[-h|--help|-v|--version] or
filename tablename[,tablename]... [-o|--operation tableop[,tableop][,tableop]]]
where
tablename - string. a list of comma seperated names of the tables whose changes
will be watched.
filename - string. The name of the module (e.g. /usr/lib/xxx.pm) or
command (e.g. /usr/bin/xxx) that handles the notification.
If it is a perl module, the module must implement the following routine:
processTableChanges(action, table_name, old_data, new_data)
Refer to notify() subroutine for the meaning of the parameters.
If it is a command, the command format should be:
command [-d|-a|-u] tablename {[colnames][rowvalues][rowvalues]...} {[colnames][rowvalues]}
tableop - it can be 'a' for add, 'd' for delete and 'u' for update.
callback - the pointer to the callback function.
Returns:
none
Comments:
If the module or the command already exists in the notification table, this subroutine
will replace it.
=cut
#-------------------------------------------------------------------------------
sub regNotification {
my $args=shift;
my $callback=shift;
my $VERSION;
my $HELP;
my $tableops;
# subroutine to display the usage
sub regnotif_usage
{
my $callbk=shift;
if (! $callbk) { return;}
my %rsp;
$rsp->{data}->[0]= "Usage:";
$rsp->{data}->[1]= " regnotif filename tablename[,tablename]... [-o|--operation tableop[,tableop][,tableop]]]";
$rsp->{data}->[2]= " where tableop can be 'a' for add, 'd' for delete and 'u' for update";
$rsp->{data}->[3]= " regnotif [-h|--help|-v|--version]";
$callbk->($rsp);
}
@ARGV=@{$args};
# parse the options
if(!GetOptions(
'o|operation=s' => \$tableops,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,))
{
&regnotif_usage($callback);
return;
}
# display the usage if -h or --help is specified
if ($::HELP) {
&regnotif_usage($callback);
return;
}
# display the version statement if -v or --verison is specified
if ($::VERSION)
{
my %rsp;
$rsp->{data}->[0]= "regnotif version 1.0";
if ($callback) {
$callback->($rsp);
}
return;
}
# must specify the file name and table names
if (@ARGV < 2)
{
&regnotif_usage($callback);
return;
}
#table operations must be a,d or u seperated by ','
if ($tableops)
{
if ($tableops !~ m/^(a|d|u)(,(a|d|u)){0,2}$/) {
my %rsp;
$rsp->{data}->[0]= "Invalid table operations: $tableops";
if ($callback) {
$callback->($rsp);
}
return;
}
}
else
{
$tableops="a,d,u";
}
my $fname=shift(@ARGV);
my $table_names=shift(@ARGV);
my $table=xCAT::Table->new("notification", -create => 1,-autocommit => 0);
if ($table) {
my %key_col = (filename=>$fname);
my %tb_cols=(tables=>$table_names, tableops=>$tableops);
$table->setAttribs(\%key_col, \%tb_cols);
$table->commit;
}
#update notification cache
xCAT::NotifHandler::sendNotifSignal();
return;
}
#--------------------------------------------------------------------------------
=head3 unregNotification
It unregisters a notification routine or a command.
Arguments:
args - the format of the ares is:
[-h|--help|-v|--version] or
filename
where
filename - string. The name of the module or command that handles the notification.
callback - the pointer to the callback funtion.
Returns:
none
=cut
#-------------------------------------------------------------------------------
sub unregNotification {
my $args=shift;
my $callback=shift;
my $VERSION;
my $HELP;
# subroutine to display the usage
sub unregnotif_usage
{
my $callbk=shift;
if (! $callbk) { return;}
my %rsp;
$rsp->{data}->[0]= "Usage:";
$rsp->{data}->[1]= " unregnotif filename";
$rsp->{data}->[2]= " unregnotif [-h|--help|-v|--version]";
$callbk->($rsp);
}
@ARGV=@{$args};
# parse the options
if(!GetOptions(
'h|help' => \$::HELP,
'v|version' => \$::VERSION,))
{
&unregnotif_usage($callback);
return;
}
# display the usage if -h or --help is specified
if ($::HELP) {
&unregnotif_usage($callback);
return;
}
# display the version statement if -v or --verison is specified
if ($::VERSION)
{
my %rsp;
$rsp->{data}->[0]= "unregnotif version 1.0";
if ($callback) {
$callback->($rsp);
}
return;
}
# must specify the node range
if (@ARGV < 1) {
&unregnotif_usage($callback);
return;
}
my $fname=shift(@ARGV);
my $table=xCAT::Table->new("notification", -create => 1,-autocommit => 0);
if ($table) {
my %key_col = (filename=>$fname);
$table->delEntries(\%key_col);
$table->commit;
}
#update notification cache
xCAT::NotifHandler::sendNotifSignal();
return;
}