#!/usr/bin/perl # The LearningOnline Network with CAPA # # lonManage supports remote management of nodes in a LonCAPA cluster. # # $Id: lonManage,v 1.8 2003/08/18 10:18:21 foxr Exp $ # # $Id: lonManage,v 1.8 2003/08/18 10:18:21 foxr Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). ## LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # # lonManage supports management of remot nodes in a lonCAPA cluster. # it is a command line tool. The following command line syntax (usage) # is supported: # # lonManage -push newfile host # Push to the lonTabs directory. Note that # must be one of: # hosts (hosts.tab) # domain (domain.tab) # # lonManage -reinit lonc host # Sends a HUP signal to the remote systems's lond. # # lonmanage -reinit lond host # Requests the remote system's lond perform the same action as if # it had received a HUP signal. # # In the above syntax, the host above is the hosts.tab name of a host, # not the IP address of the host. # # $Log: lonManage,v $ # Revision 1.8 2003/08/18 10:18:21 foxr # Completed PushFile function in terms of # - ValidHost - Determines if target host is valid. # - Transact - Performs one of the valid transactions with the # appropriate lonc<-->lond client/server pairs. # # Revision 1.7 2003/08/18 09:56:01 foxr # 1. Require to be run as root. # 2. Catch case where no operation switch is supplied and put out usage. # 3. skeleton/comments for PushFile function. # # Revision 1.6 2003/08/12 11:02:59 foxr # Implement command switch dispatching. # # Revision 1.5 2003/08/12 10:55:42 foxr # Complete command line parsing (tested) # # Revision 1.4 2003/08/12 10:40:44 foxr # Get switch parsing right. # # Revision 1.3 2003/08/12 10:22:35 foxr # Put in parameter parsing infrastructure # # Revision 1.2 2003/08/12 09:58:49 foxr # Add usage and skeleton documentation. # # use strict; # Because it's good practice. use English; # Cause I like meaningful names. use Getopt::Long; sub Usage { print "Usage:"; print < newfile host Push to the lonTabs directory. Note that must be one of: hosts (hosts.tab) domain (domain.tab) lonManage --reinit=lonc host Sends a HUP signal to the remote systems's lond. lonManage --reinit=lond host Requests the remote system's lond perform the same action as if it had received a HUP signal. In the above syntax, the host above is the hosts.tab name of a host, not the IP address of the host. USAGE } # # Use Getopt::Long to parse the parameters of the program. # # Return value is a list consisting of: # A 'command' which is one of: # push - table push requested. # reinit - reinit requested. # Additional parameters as follows: # for push: Tablename, hostname # for reinit: Appname hostname # # This function does not validation of the parameters of push and # reinit. # # returns a list. The first element of the list is the operation name # (e.g. reinit or push). The second element is the switch parameter. # for push, this is the table name, for reinit, this is the process name. # Additional elements of the list are the command argument. The count of # command arguments is validated, but not their semantics. # # returns an empty list if the parse fails. # sub ParseArgs { my $pushing = ''; my $reinitting = ''; if(!GetOptions('push=s' => \$pushing, 'reinit=s' => \$reinitting)) { return (); } # Require exactly one of --push and --reinit my $command = ''; my $commandarg = ''; my $paramcount = @ARGV; # Number of additional arguments. if($pushing ne '') { # --push takes in addition a table, and a host: # if($paramcount != 2) { return (); # Invalid parameter count. } if($command ne '') { return (); } else { $command = 'push'; $commandarg = $pushing; } } if ($reinitting ne '') { # --reinit takes in addition just a host name if($paramcount != 1) { return (); } if($command ne '') { return (); } else { $command = 'reinit'; $commandarg = $reinitting; } } # Build the result list: my @result = ($command, $commandarg); my $i; for($i = 0; $i < $paramcount; $i++) { push(@result, $ARGV[$i]); } return @result; } sub ValidHost { return 1; } sub Transact { } # # Called to push a file to the remote system. # The only legal files to push are hosts.tab and domain.tab. # Security is somewhat improved by # # - Requiring the user run as root. # - Connecting with lonc rather than lond directly ensuring this is a loncapa # host # - We must appear in the remote host's hosts.tab file. # - The host must appear in our hosts.tab file. # # Parameters: # tablename - must be one of hosts or domain. # tablefile - name of the file containing the table to push. # host - name of the host to push this file to. # sub PushFile { my $tablename = shift; my $tablefile = shift; my $host = shift; # Open the table file: if(!open(TABLEFILE, "<$tablefile")) { die "ENOENT - No such file or directory $tablefile"; } # Require that the host be valid: if(!ValidHost($host)) { die "EHOSTINVAL - Invalid host $host"; # Ok so I invented this 'errno'. } # Read in the file. If the table name is valid, push it. my @table = ; # These files are pretty small. close TABLEFILE; if( ($tablename eq "host") || ($tablename eq "domain")) { Transact($host, "pushfile:$tablename:",\@table); } else { die "EINVAL - Invalid parameter. tablename: $tablename must be host or domain"; } } sub ReinitProcess { print "Reinitializing a process\n"; } #--------------------------- Entry point: -------------------------- # Parse the parameters # If command parsing failed, then print usage: my @params = ParseArgs; my $nparam = @params; if($nparam == 0) { Usage; exit -1; } # # Next, ensure we are running as EID root. # if ($EUID != 0) { die "ENOPRIV - No privilege for requested operation" } # Based on the operation requested invoke the appropriate function: my $operation = shift @params; if($operation eq "push") { # push tablename filename host my $tablename = shift @params; my $tablefile = shift @params; my $host = shift @params; PushFile($tablename, $tablefile, $host); } elsif($operation eq "reinit") { # reinit processname host. my $process = shift @params; my $host = shift @params; ReinitProcess($process, $host); } else { Usage; } exit 0; =head1 NAME lonManage - Command line utility for remote management of lonCAPA cluster nodes. =head1 SYNOPSIS Usage: B newfile host> Push to the lonTabs directory. Note that must be one of: hosts (hosts.tab) domain (domain.tab) B Sends a HUP signal to the remote systems's lond. B Requests the remote system's lond perform the same action as if it had received a HUP signal. In the above syntax, the host above is the hosts.tab name of a host, not the IP address of the host. =head1 DESCRIPTION =head1 PREREQUISITES =item strict =item Getopt::Long =item English =head1 CATEGORIES Command line utility =cut