version 1.1, 2003/08/12 09:46:27
|
version 1.10, 2003/08/18 10:43:31
|
Line 49
|
Line 49
|
# In the above syntax, the host above is the hosts.tab name of a host, |
# In the above syntax, the host above is the hosts.tab name of a host, |
# not the IP address of the host. |
# not the IP address of the host. |
# |
# |
|
# $Log$ |
|
# Revision 1.10 2003/08/18 10:43:31 foxr |
|
# Code/test ValidHost. The hosts.tab and the perl variables are read in as |
|
# global hashes as a side effect. May later want to clean this up by making |
|
# a separate getconfig function and hoisting the config reads into that. |
|
# |
|
# Revision 1.9 2003/08/18 10:25:46 foxr |
|
# Write ReinitProcess function in terms of ValidHost and Transact. |
|
# |
|
# 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. |
|
# |
|
# |
|
|
|
# Modules required: |
|
|
|
use strict; # Because it's good practice. |
|
use English; # Cause I like meaningful names. |
|
use Getopt::Long; |
|
use LONCAPA::Configuration; # To handle configuration I/O. |
|
|
|
# File scoped variables: |
|
|
|
my %perlvar; # Perl variable defs from apache config. |
|
my %hostshash; # Host table as a host indexed hash. |
|
|
|
sub Usage { |
|
print "Usage:"; |
|
print <<USAGE; |
|
lonManage --push=<tablename> newfile host |
|
Push <tablename> to the lonTabs directory. Note that |
|
<tablename> 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; |
|
} |
|
# |
|
# Determine if the target host is valid. |
|
# This is done by reading the current hosts.tab file. |
|
# For the host to be valid, it must be inthe file. |
|
# |
|
# Parameters: |
|
# host - Name of host to check on. |
|
# Returns: |
|
# true if host is valid. |
|
# false if host is invalid. |
|
# |
|
sub ValidHost { |
|
my $host = shift; |
|
|
|
my $perlvarref = LONCAPA::Configuration::read_conf('loncapa.conf'); |
|
%perlvar = %{$perlvarref}; |
|
my $hoststab = LONCAPA::Configuration::read_hosts( |
|
"$perlvar{'lonTabDir'}/hosts.tab"); |
|
%hostshash = %{$hoststab}; |
|
|
|
return defined $hostshash{$host}; |
|
|
|
} |
|
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 = <TABLEFILE>; # 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"; |
|
} |
|
} |
|
# |
|
# This function is called to reinitialize a server in a remote host. |
|
# The servers that can be reinitialized are: |
|
# - lonc - The lonc client process. |
|
# - lond - The lond daemon. |
|
# NOTE: |
|
# Reinitialization in this case means re-scanning the hosts table, |
|
# starting new lond/lonc's as approprate and stopping existing lonc/lond's. |
|
# |
|
# Parameters: |
|
# process - The name of the process to reinit (lonc or lond). |
|
# host - The host in which this reinit will happen. |
|
# |
|
sub ReinitProcess { |
|
my $process = shift; |
|
my $host = shift; |
|
|
|
# Ensure the host is valid: |
|
|
|
if(!ValidHost($host)) { |
|
die "EHOSTINVAL - Invalid host $host"; |
|
} |
|
# Ensure target process selector is valid: |
|
|
|
if(($process eq "lonc") || |
|
($process eq "lond")) { |
|
Transact($host, "reinit:$process"); |
|
} else { |
|
die "EINVAL -Invalid parameter. Process $process must be lonc or lond"; |
|
} |
|
} |
|
#--------------------------- 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<lonManage --push=<tablename> newfile host> |
|
Push <tablename> to the lonTabs directory. Note that |
|
<tablename> must be one of: |
|
hosts (hosts.tab) |
|
domain (domain.tab) |
|
|
|
B<lonManage --reinit=lonc host> |
|
Sends a HUP signal to the remote systems's lond. |
|
|
|
B<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. |
|
|
|
|
|
=head1 DESCRIPTION |
|
|
|
=head1 PREREQUISITES |
|
|
|
=item strict |
|
=item Getopt::Long |
|
=item English |
|
|
|
=head1 CATEGORIES |
|
Command line utility |
|
|
|
=cut |