[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--