[LON-CAPA-cvs] cvs: loncom / clusteradmin
foxr
foxr@source.lon-capa.org
Mon, 16 Mar 2009 09:43:00 -0000
foxr Mon Mar 16 09:43:00 2009 EDT
Modified files:
/loncom clusteradmin
Log:
Forgot to commit final working version
Index: loncom/clusteradmin
diff -u loncom/clusteradmin:1.1 loncom/clusteradmin:1.2
--- loncom/clusteradmin:1.1 Mon Feb 2 11:58:59 2009
+++ loncom/clusteradmin Mon Mar 16 09:43:00 2009
@@ -16,7 +16,7 @@
The action is specified by the 'command' parameter which may have additional arguments.
All communications with remote clients are made critical so that
-they will eventually happen even if the host we want to talk with
+they will eventually happen even if the147 host we want to talk with
is dead.
@@ -37,11 +37,24 @@
=back
+=head1 ASSUMPTIONS
+
+Assume that loncapa is installedin /home/httpd/lib/perl so that we can use
+it's modules. If this is not the case, you mus modify the
+use lib line in the program before you can use it.
+
=cut
use strict;
+# I'm not sure if there's a better way to establish the location of the libs:
+
+use lib ('/home/httpd/lib/perl');
+
+use LONCAPA::Configuration;
+use File::Basename;
+use Apache::lonnet;
#----------------------------------------------------------------------------------
#
@@ -103,3 +116,168 @@
}
}
#-----------------------------------------------------------------------------------
+
+#
+# Provide usage/help string:
+#
+
+sub usage {
+ print STDERR "Usage:\n";
+ print STDERR " clusteradmin subcommand [args]\n";
+ print STDERR "Where:\n";
+ print STDERR " subcommand describes what to actually do:\n";
+ print STDERR " help - Prints this message (args ignored)\n";
+ print STDERR " update - Updates an administrative file\n";
+ print STDERR " args is one of dns_hosts.tab or dns_domain.tab\n";
+
+}
+
+&define_command("help", \&usage);
+
+
+#--------------------------------------------------------------------------------
+#
+# File update subsystem:
+
+
+# Given the basename of an administrative file, return the
+# full path to that file.
+# Pre-requisistes:
+# Requires that LONCAPA::Configuration is in the use lib path.
+# Parameters:
+# $basename - Base name of the file to locate.
+# Returns:
+# Full path to that file.
+#
+
+my $config_vars = LONCAPA::Configuration::read_conf('loncapa.conf');
+my %config = %{$config_vars};
+
+
+sub construct_table_path {
+ my ($basename) = @_;
+ my $directory = $config{'lonTabDir'};
+
+ return $directory . '/' . $basename;
+}
+
+# Returns the set of hosts that are specified as DNS hosts in the hosts.tab file.
+# Those are the ones with a ^ in column one.
+#
+# Returns:
+# The list of host that are DNS hosts.
+#
+sub get_dns_hosts()
+{
+ my @result;
+ my $hosts_tab = &construct_table_path('hosts.tab');
+ open(HOSTS, "<$hosts_tab");
+ while (my $line = <HOSTS>) {
+ chomp($line);
+ if ($line =~ /^\^/) {
+ $line =~ s/^\^//; # Get rid of leading ^
+ $line =~ s/\s*$//; # and any trailing whitespace.
+ push(@result, $line);
+ }
+ }
+ return (@result);
+}
+
+# Actually push the new files to the systems to update. This is done as a critical
+# transaction so that the files eventually get pushed, even if the target hosts
+# are down about now.
+#
+# Parameters:
+# specifier - The specifier to hand in the push transaction. This
+# identifies the target file in the remote lond process.
+# pushfile - Full path to the file to push.
+# hosts - Reference to an array of hosts into which the file should be pushed.
+#
+# Returns:
+# 1 - Success.
+# 0 - Failure with appropriate output to stderr.
+#
+sub push_file {
+ my ($specifier, $pushfile, $hosts) = @_;
+
+ # Read in the entire file:
+
+ my $contents;
+ my $line;
+ open(FILE, "<$pushfile");
+ while ($line = <FILE>) {
+ $contents .= $line;
+ }
+
+
+ # Construct the transaction for safety we encrypt the transaction
+ #
+ my $cmd = "encrypt:pushfile:$specifier:$contents";
+
+ # Iterate over the hosts and run cmd as a critical
+ # operation:
+
+ foreach my $host (@$hosts) {
+ my $loncapa_name = &Apache::lonnet::host_from_dns($host);
+ my $reply = &Apache::lonnet::critical($cmd, $loncapa_name);
+ if ($reply ne 'ok') {
+ print STDERR "Reply from $host ($loncapa_name) not 'ok' was: $reply\n";
+ }
+ }
+
+}
+
+#
+# Controls the push of a file to the servers that deserve to get it.
+# Parameters:
+# args - Tail of the command line (array reference).
+# Returns:
+# 1 - Success.
+# 0 - Failure (printing messages to stderr.
+#
+sub update_file {
+ my ($args) = @_;
+
+ if (scalar(@$args) != 1) {
+ print STDERR "Incorrect number of command arguments\n";
+ &usage();
+ return 0;
+ } else {
+ my $filename = shift(@$args);
+
+ # Validate the filename:
+
+ if ($filename eq 'dns_hosts.tab' || $filename eq 'dns_domain.tab') {
+ my $pushfile = &construct_table_path($filename);
+ my $specifier = basename($filename, ('.tab'));
+ my @hosts = (&get_dns_hosts());
+ return &push_file($specifier, $pushfile, \@hosts);
+ } else {
+ print STDERR "Only dns_hosts.tab or dns_domain.tab can be updated\n";
+ &usage();
+ return 0;
+ }
+ }
+}
+&define_command("update", \&update_file);
+#---------------------------------------------------------------------------------
+#
+# Program entry point. Decode the subcommand from the args array and
+# dispatch to the appropriate command processor.
+#
+
+my $argc = scalar(@ARGV);
+if ($argc == 0) {
+ print STDERR "Missing subcommand\n";
+ &usage();
+ exit(-1);
+}
+
+my $subcommand = shift(@ARGV); # argv now the tail.
+
+if (!&dispatch_command($subcommand, \@ARGV)) {
+ exit(0);
+} else {
+ exit(-1);
+}
+