[LON-CAPA-cvs] cvs: loncom / lonManage
foxr
lon-capa-cvs@mail.lon-capa.org
Mon, 22 Dec 2003 11:02:36 -0000
This is a MIME encoded message
--foxr1072090956
Content-Type: text/plain
foxr Mon Dec 22 06:02:36 2003 EDT
Modified files:
/loncom lonManage
Log:
Add stubs and base logic for --edit switch.
--foxr1072090956
Content-Type: text/plain
Content-Disposition: attachment; filename="foxr-20031222060236.txt"
Index: loncom/lonManage
diff -u loncom/lonManage:1.25 loncom/lonManage:1.26
--- loncom/lonManage:1.25 Tue Nov 4 06:52:06 2003
+++ loncom/lonManage Mon Dec 22 06:02:36 2003
@@ -3,9 +3,9 @@
#
# lonManage supports remote management of nodes in a LonCAPA cluster.
#
-# $Id: lonManage,v 1.25 2003/11/04 11:52:06 foxr Exp $
+# $Id: lonManage,v 1.26 2003/12/22 11:02:36 foxr Exp $
#
-# $Id: lonManage,v 1.25 2003/11/04 11:52:06 foxr Exp $
+# $Id: lonManage,v 1.26 2003/12/22 11:02:36 foxr Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -111,6 +111,18 @@
If [host] is omitted, all hosts in the hosts.tab file are iterated
over.
+lonManage [--myname=host --hosts=table] --edit=<tablename> editscript [host]
+ Requests lond edit the hosts or domain table (selected by
+ tablename) with the editing command in editscript. If
+ host is supplied the individual host is operated on,
+ otherwise, the entire cluster is operated on.
+ The edit file has edit request, one per line of the form:
+ append|newline
+ replace|key|newline
+ delete|key
+ The key is a loncapa hostname if editing the host file
+ or a domain name if editing the domain table file.
+
For all of the above syntaxes if --myname=host and --hosts=table are
supplied (both must be present), the utility runs in standalone mode
presenting itself to the world as 'host' and using the hosts.tab file
@@ -160,23 +172,23 @@
my $state = $connection->GetState;
while(($connection->GetState ne "Idle") && (!$error)) {
- #
- # Figure out what the connection wants. read/write and wait for it
- # or for the timeout.
- #
+ #
+ # Figure out what the connection wants. read/write and wait for it
+ # or for the timeout.
+ #
my $wantread = $connection->WantReadable;
my $poll = new IO::Poll;
$poll->mask($Socket, => $wantread ? POLLIN : POLLOUT);
- $poll->poll($timeout);
- my $done = $poll->handles();
- if(scalar($done) == 0) { # no handles ready... timeout!!
+ my $handlecount = $poll->poll($timeout);
+ if($handlecount == 0) { # no handles ready... timeout!!
$returnstatus = "error:";
$returnstatus .= "Timeout in state $state\n";
$error = 1;
} else {
+ my $done = $poll->handles();
my $status;
$status = $wantread ? $connection->Readable :
- $connection->Writable;
+ $connection->Writable;
if($status != 0) {
$returnstatus = "error:";
$returnstatus .= " I/O failed in state $state\n";
@@ -215,12 +227,12 @@
my $returnstatus = "ok"; # Optimistic!!.
my $state = $connection->GetState;
- if($state ne "Connected") {
- print "Error: Initial lond connection state: $state should be Connected\n";
- return "error";
- }
+ if($state ne "Connected") {
+ print "Error: Initial lond connection state: $state should be Connected\n";
+ return "error";
+ }
- return SequenceStateMachine($connection, $TransitionTimeout);
+ return SequenceStateMachine($connection, $TransitionTimeout);
}
#
# Perform a transaction with the remote lond.
@@ -245,11 +257,11 @@
$connection->InitiateTransaction($command);
my $status = SequenceStateMachine($connection, $TransitionTimeout);
- if($status eq "ok") {
- $retval = $connection->GetReply;
- } else {
- $retval = $status;
- }
+ if($status eq "ok") {
+ $retval = $connection->GetReply;
+ } else {
+ $retval = $status;
+ }
return $retval;
}
@@ -267,31 +279,19 @@
my $host = shift;
- my $connection = MakeLondConnection($host);
- if ($connection eq undef) {
- return "Connect Failed";
- }
- my $reply = NegotiateStartup($connection);
- if($reply ne "ok") {
- return "connection negotiation failed";
- }
- my $reply = PerformTransaction($connection, $cmd);
- return $reply;
+ my $connection = MakeLondConnection($host);
+ if ($connection eq undef) {
+ return "Connect Failed";
+ }
+ my $reply = NegotiateStartup($connection);
+ if($reply ne "ok") {
+ return "connection negotiation failed";
+ }
+ my $reply = PerformTransaction($connection, $cmd);
+ return $reply;
- # my ($cmd,$server)=@_;
- # my $peerfile="$perlvar{'lonSockDir'}/$server";
- # my $client=IO::Socket::UNIX->new(Peer =>"$peerfile",
- # Type => SOCK_STREAM,
- # Timeout => 10)
- # or return "con_lost";
- # print $client "$cmd\n";
- # my $answer=<$client>;
- # if (!$answer) { $answer="con_lost"; }
- # chomp($answer);
- # return $answer;
}
-# >>> BUGBUG <<<
#
# Use Getopt::Long to parse the parameters of the program.
#
@@ -317,74 +317,114 @@
sub ParseArgs {
- my $pushing = '';
+ my $pushing = '';
my $reinitting = '';
-
+ my $editing = '';
+
if(!GetOptions('push=s' => \$pushing,
- 'reinit=s' => \$reinitting,
- 'myname=s' => \$MyHost,
- 'hosts=s' => \$ForeignHostTab)) {
- return ();
- }
+ 'reinit=s' => \$reinitting,
+ 'edit=s' => \$editing,
+ 'myname=s' => \$MyHost,
+ 'hosts=s' => \$ForeignHostTab)) {
+ return ();
+ }
# The --myname and --hosts switch must have values and
# most both appear if either appears:
- if(($MyHost ne "") && ($ForeignHostTab eq "")) {
- return ();
- }
- if(($ForeignHostTab ne "") && ($MyHost eq "")) {
- 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 an optional host:
- #
- if(($paramcount != 2) && ($paramcount != 1)) {
- return (); # Invalid parameter count.
- }
- if($command ne '') {
- return ();
- } else {
+ if(($MyHost ne "") && ($ForeignHostTab eq "")) {
+ return ();
+ }
+ if(($ForeignHostTab ne "") && ($MyHost eq "")) {
+ return ();
+ }
+
+ # Require exactly one of --push, --reinit, or --edit
+
+ my $command = '';
+ my $commandarg = '';
+ my $paramcount = @ARGV; # Number of additional arguments.
+
+ my $commands = 0; # Number of commands seen.
+
+ if($pushing ne '') {
+
+ # --push takes in addition a table, and an optional host:
+ #
+
+ if(($paramcount != 2) && ($paramcount != 1)) {
+ return (); # Invalid parameter count.
+ }
- $command = 'push';
- $commandarg = $pushing;
+ $commands++; # Count a command seen.
+ $command = 'push';
+ $commandarg = $pushing;
}
- }
- if ($reinitting ne '') {
+ if ($reinitting ne '') {
# --reinit takes in addition just an optional host name
- if($paramcount > 1) {
- return ();
- }
- if($command ne '') {
- return ();
- } else {
- $command = 'reinit';
- $commandarg = $reinitting;
+ if($paramcount > 1) {
+ return ();
+ }
+ $commands++; # Count a command seen.
+ $command = 'reinit';
+ $commandarg = $reinitting;
}
- }
+
+ # --edit takes a script file and optional host name.
+ #
+ if ($editing ne "") {
+ if(($paramcount != 2) && ($paramcount != 1)) {
+ return (); # Invalid parameter count.
+ }
+
+ $commands++; # Count a command seen.
+ $command = 'edit';
+ $commandarg = $editing;
+ }
+
+ # At this point, $commands must be 1 or else we've seen
+ # The wrong number of command switches:
+
+ if($commands != 1) {
+ return ();
+ }
# Build the result list:
- my @result = ($command, $commandarg);
- my $i;
- for($i = 0; $i < $paramcount; $i++) {
- push(@result, $ARGV[$i]);
- }
+ my @result = ($command, $commandarg);
+ my $i;
+ for($i = 0; $i < $paramcount; $i++) {
+ push(@result, $ARGV[$i]);
+ }
return @result;
}
#
+# Build the editor script. This function:
+# - Opens the edit script file.
+# - Reads each line of the edit script file
+# - Replaces the ending \n with a /
+# - Appends it to the EditScript variable.
+# - Returns the contents of the EditScript variable.
+# Parameters:
+# tabletype - The type of table being built:
+# hosts or domain
+# scriptname - The script input file.
+#
+sub BuildEditScript {
+ my $TableType = shift;
+ my $ScriptName = shift;
+
+ #Stub
+
+ my @EditScript = (
+ "$TableType\:append|".
+ "nscll2\:nscl\:library\:lonkashy.nscl.msu.edu\:35.8.32.89"
+ );
+ return \@EditScript;
+}
# Read the loncapa configuration stuff. If ForeignHostTab is empty,
# assume we are part of a loncapa cluster and read the hosts.tab
# file from the config directory. Otherwise, ForeignHossTab
@@ -393,22 +433,24 @@
#
sub ReadConfig {
- if($ForeignHostTab eq "") {
- my $perlvarref = LondConnection::read_conf('loncapa.conf');
- %perlvar = %{$perlvarref};
- my $hoststab = LondConnection::read_hosts(
- "$perlvar{'lonTabDir'}/hosts.tab");
- %hostshash = %{$hoststab};
- $MyHost = $perlvar{lonHostID}; # Set hostname from vars.
- $ServerPort = $perlvar{londPort};
- } else {
+
+
+ if($ForeignHostTab eq "") {
+ my $perlvarref = LondConnection::read_conf('loncapa.conf');
+ %perlvar = %{$perlvarref};
+ my $hoststab = LondConnection::read_hosts(
+ "$perlvar{lonTabDir}/hosts.tab");
+ %hostshash = %{$hoststab};
+ $MyHost = $perlvar{lonHostID}; # Set hostname from vars.
+ $ServerPort = $perlvar{londPort};
+ } else {
- LondConnection::ReadForeignConfig($MyHost, $ForeignHostTab);
- my $hoststab = LondConnection::read_hosts($ForeignHostTab); # we need to know too.
- %hostshash = %{$hoststab};
- $ServerPort = $DefaultServerPort;
- }
-
+ LondConnection::ReadForeignConfig($MyHost,
+ $ForeignHostTab);
+ my $hoststab = LondConnection::read_hosts($ForeignHostTab); # we need to know too.
+ %hostshash = %{$hoststab};
+ $ServerPort = $DefaultServerPort;
+ }
}
#
# Determine if the target host is valid.
@@ -454,23 +496,23 @@
my $body;
my $i;
- if(scalar @ARG) {
- $body = shift;
- $haveBody = 1;
- }
+ if(scalar @ARG) {
+ $body = shift;
+ $haveBody = 1;
+ }
# Construct the command to send to the server:
- my $request = "encrypt\:"; # All requests are encrypted.
- $request .= $command;
- if($haveBody) {
- $request .= "\:";
- my $bodylines = scalar @$body;
- for($i = 0; $i < $bodylines; $i++) {
- $request .= $$body[$i];
- }
- } else {
- $request .= "\n";
- }
+ my $request = "encrypt\:"; # All requests are encrypted.
+ $request .= $command;
+ if($haveBody) {
+ $request .= "\:";
+ my $bodylines = scalar @$body;
+ for($i = 0; $i < $bodylines; $i++) {
+ $request .= $$body[$i];
+ }
+ } else {
+ $request .= "\n";
+ }
# Body is now built... transact with lond..
my $answer = subreply($request, $host);
@@ -494,7 +536,7 @@
# tablefile - name of the file containing the table to push.
# host - name of the host to push this file to.
#
-# >>>BUGBUG<<< This belongs in lonnet.pm.
+#
#
sub PushFile {
my $tablename = shift;
@@ -503,28 +545,47 @@
# Open the table file:
- if(!open(TABLEFILE, "<$tablefile")) {
- die "ENOENT - No such file or directory $tablefile";
- }
+ 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'.
- }
+ 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;
+ my @table = <TABLEFILE>; # These files are pretty small.
+ close TABLEFILE;
- if( ($tablename eq "host") ||
- ($tablename eq "domain")) {
- print("Pushing $tablename to $host\n");
- Transact($host, "pushfile:$tablename",\@table);
- } else {
- die "EINVAL - Invalid parameter. tablename: $tablename must be host or domain";
- }
+ if( ($tablename eq "host") ||
+ ($tablename eq "domain")) {
+ print("Pushing $tablename to $host\n");
+ Transact($host, "pushfile:$tablename",\@table);
+ } else {
+ die "EINVAL - Invalid parameter. tablename: $tablename must be host or domain";
+ }
+}
+#
+# This function forms and executes an edit file with a
+# remote lond server. We build the full transaction string
+# and use Transact to perform the transaction.
+# Paramters:
+# host - loncapa name of host to operate on.
+# body - Body of the command. We send:
+# edit:$body as the command request.
+#
+sub EditFile {
+ my $host = shift;
+ my $body = shift;
+
+ if(!ValidHost($host)) {
+ die "EHOSTINVAL - Invalid host $host";
+ }
+ Transact($host, "edit", $body);
}
+
#
# This function is called to reinitialize a server in a remote host.
# The servers that can be reinitialized are:
@@ -541,23 +602,23 @@
# >>>BUGBUG<<<< This belongs in lonnet.pm
#
sub ReinitProcess {
- my $process = shift;
- my $host = shift;
+ my $process = shift;
+ my $host = shift;
# Ensure the host is valid:
- if(!ValidHost($host)) {
- die "EHOSTINVAL - Invalid host $host";
- }
+ if(!ValidHost($host)) {
+ die "EHOSTINVAL - Invalid host $host";
+ }
# Ensure target process selector is valid:
- if(($process eq "lonc") ||
- ($process eq "lond")) {
- print("Reinitializing $process in $host\n");
- Transact($host, "reinit:$process");
- } else {
- die "EINVAL -Invalid parameter. Process $process must be lonc or lond";
- }
+ if(($process eq "lonc") ||
+ ($process eq "lond")) {
+ print("Reinitializing $process in $host\n");
+ Transact($host, "reinit:$process");
+ } else {
+ die "EINVAL -Invalid parameter. Process $process must be lonc or lond";
+ }
}
#--------------------------- Entry point: --------------------------
@@ -595,11 +656,11 @@
my $tablefile = shift @params;
my $host = shift @params;
if($host) {
- PushFile($tablename, $tablefile, $host);
+ PushFile($tablename, $tablefile, $host);
} else { # Push to whole cluster.
- foreach my $host (keys %hostshash) {
- PushFile($tablename, $tablefile, $host);
- }
+ foreach my $host (keys %hostshash) {
+ PushFile($tablename, $tablefile, $host);
+ }
}
} elsif($operation eq "reinit") { # reinit processname host.
@@ -612,9 +673,21 @@
ReinitProcess($process,$host);
}
}
-}
+} elsif($operation eq "edit") { # Edit a table.
+ my $tablename = shift @params;
+ my $scriptfile = shift @params;
+ my $host = shift @params;
+ my $CommandBody = BuildEditScript($tablename, $scriptfile);
+ if ($host) {
+ EditFile($host, $CommandBody);
+ } else {
+ foreach my $ClusterMember (keys %hostshash) {
+ EditFile($ClusterMember, $CommandBody);
+ }
+ }
+}
else {
- Usage;
+ Usage;
}
exit 0;
@@ -634,12 +707,25 @@
B<lonManage --reinit=lonc host>
Sends a HUP signal to the remote systems's lond.
- B<lonmanage --reinit=lond host>
+ 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.
+ B<lonManage --edit=<tablename> editscript host>
+ Requests the remote system's lond perform an edit
+ on <tablename> editscript supplies a set of
+ editing commands. Each edit command is one of :
+
+ append|key|newline
+ delete|key|
+ replace|key|newline
+
+ The key above is the value of the loncapa host name
+ in the file.
+
+In the above syntax, the host above is the
+hosts.tab name of a host,
+not the IP address of the host.
=head1 DESCRIPTION
@@ -650,6 +736,7 @@
=item Getopt::Long
=item English
=item IO::Socket::UNIX
+=item LONCAPA::LondConnection
=head1 KEY Subroutines.
--foxr1072090956--