version 1.2, 2009/03/16 09:43:00
|
version 1.8, 2018/08/20 22:42:05
|
Line 1
|
Line 1
|
#!/usr/bin/perl |
#!/usr/bin/perl |
|
# The LearningOnline Network with CAPA |
|
# Push admin files from cluster manager to cluster's "name servers". |
|
# |
|
# $Id$ |
|
# |
|
# 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/ |
|
|
=pod |
=pod |
|
|
Line 8
|
Line 33
|
|
|
=head1 DESCRIPTION |
=head1 DESCRIPTION |
|
|
Performs an adiminstrative action on all hosts in the current dns_hosts.tab |
Performs an adminstrative update on (a) "DNS" hosts or domains in the current |
file. For this to work, the current host must be the cluster administrator |
dns_hosts.tab or dns_domain.tab files, or (b) update of the Certificate |
on the target systems. That is this must be a host in managers.tab |
Revocation List (CRL) file for the cluster. |
|
|
|
For this to work, the current host must be the cluster administrator |
|
on the target systems. That is this must be a host in managers.tab. |
Furthermore, lonc must be running on this system. |
Furthermore, lonc must be running on this system. |
|
|
The action is specified by the 'command' parameter which may have additional arguments. |
The action is specified by the 'command' parameter which may have additional arguments. |
|
|
All communications with remote clients are made critical so that |
All communications with remote clients are made critical so that |
they will eventually happen even if the147 host we want to talk with |
they will eventually happen even if the host we want to talk with |
is dead. |
is dead. |
|
|
|
|
Line 39 on this system. 'file' is the name of t
|
Line 67 on this system. 'file' is the name of t
|
|
|
=head1 ASSUMPTIONS |
=head1 ASSUMPTIONS |
|
|
Assume that loncapa is installedin /home/httpd/lib/perl so that we can use |
Assume that loncapa is installed in /home/httpd/lib/perl so that we can use |
it's modules. If this is not the case, you mus modify the |
it's modules. If this is not the case, you must modify the |
use lib line in the program before you can use it. |
use lib line in the program before you can use it. |
|
|
|
|
Line 128 sub usage {
|
Line 156 sub usage {
|
print STDERR " subcommand describes what to actually do:\n"; |
print STDERR " subcommand describes what to actually do:\n"; |
print STDERR " help - Prints this message (args ignored)\n"; |
print STDERR " help - Prints this message (args ignored)\n"; |
print STDERR " update - Updates an administrative file\n"; |
print STDERR " update - Updates an administrative file\n"; |
print STDERR " args is one of dns_hosts.tab or dns_domain.tab\n"; |
print STDERR " args is one of dns_hosts.tab, dns_domain.tab\n"; |
|
print STDERR " or loncapaCAcrl.pem\n"; |
|
|
} |
} |
|
|
Line 152 sub usage {
|
Line 181 sub usage {
|
|
|
my $config_vars = LONCAPA::Configuration::read_conf('loncapa.conf'); |
my $config_vars = LONCAPA::Configuration::read_conf('loncapa.conf'); |
my %config = %{$config_vars}; |
my %config = %{$config_vars}; |
|
my $logfile = $config{'lonDaemons'}.'/logs/dns_updates.log'; |
|
|
|
|
sub construct_table_path { |
sub construct_table_path { |
my ($basename) = @_; |
my ($basename) = @_; |
my $directory = $config{'lonTabDir'}; |
my $directory; |
|
if ($basename eq 'managers.tab') { |
|
$directory = $config{'lonTabDir'}; |
|
} elsif ($basename eq 'loncapaCAcrl.pem') { |
|
$directory = $config{'lonCertificateDirectory'}; |
|
} elsif ($basename =~ /^(dns_|)(hosts|domain)\.tab$/) { |
|
$directory = $config{'lonTabDir'}; |
|
} |
return $directory . '/' . $basename; |
return $directory . '/' . $basename; |
} |
} |
|
|
Line 171 sub get_dns_hosts()
|
Line 207 sub get_dns_hosts()
|
{ |
{ |
my @result; |
my @result; |
my $hosts_tab = &construct_table_path('hosts.tab'); |
my $hosts_tab = &construct_table_path('hosts.tab'); |
open(HOSTS, "<$hosts_tab"); |
if (open(HOSTS,'<',$hosts_tab)) { |
while (my $line = <HOSTS>) { |
while (my $line = <HOSTS>) { |
chomp($line); |
chomp($line); |
if ($line =~ /^\^/) { |
if ($line =~ /^\^/) { |
$line =~ s/^\^//; # Get rid of leading ^ |
if ($line =~ /^\^([\w.\-]+)/) { |
$line =~ s/\s*$//; # and any trailing whitespace. |
push(@result,$1); |
push(@result, $line); |
} |
} |
} |
|
} |
} |
} |
return (@result); |
return (@result); |
} |
} |
Line 198 sub get_dns_hosts()
|
Line 235 sub get_dns_hosts()
|
# 0 - Failure with appropriate output to stderr. |
# 0 - Failure with appropriate output to stderr. |
# |
# |
sub push_file { |
sub push_file { |
my ($specifier, $pushfile, $hosts) = @_; |
my ($specifier, $pushfile, $hosts, $fh) = @_; |
|
|
# Read in the entire file: |
# Read in the entire file: |
|
|
my $contents; |
my $contents; |
my $line; |
my $line; |
open(FILE, "<$pushfile"); |
open(FILE,'<',$pushfile); |
while ($line = <FILE>) { |
while ($line = <FILE>) { |
$contents .= $line; |
$contents .= $line; |
} |
} |
Line 217 sub push_file {
|
Line 254 sub push_file {
|
# Iterate over the hosts and run cmd as a critical |
# Iterate over the hosts and run cmd as a critical |
# operation: |
# operation: |
|
|
|
my @ids=&Apache::lonnet::current_machine_ids(); |
foreach my $host (@$hosts) { |
foreach my $host (@$hosts) { |
my $loncapa_name = &Apache::lonnet::host_from_dns($host); |
my $loncapa_name = &Apache::lonnet::host_from_dns($host); |
|
next if (grep(/^\Q$loncapa_name\E$/,@ids)); |
my $reply = &Apache::lonnet::critical($cmd, $loncapa_name); |
my $reply = &Apache::lonnet::critical($cmd, $loncapa_name); |
if ($reply ne 'ok') { |
my $msg; |
print STDERR "Reply from $host ($loncapa_name) not 'ok' was: $reply\n"; |
if ($reply eq 'ok') { |
} |
$msg = "$pushfile pushed to $host ($loncapa_name): $reply\n"; |
|
} else { |
|
$msg = "Reply from $host ($loncapa_name) not 'ok' was: $reply\n"; |
|
} |
|
print $fh $msg; |
|
print STDERR $msg; |
} |
} |
|
return; |
} |
} |
|
|
# |
# |
Line 247 sub update_file {
|
Line 291 sub update_file {
|
|
|
# Validate the filename: |
# Validate the filename: |
|
|
if ($filename eq 'dns_hosts.tab' || $filename eq 'dns_domain.tab') { |
if (($filename eq 'dns_hosts.tab') || ($filename eq 'dns_domain.tab') || |
my $pushfile = &construct_table_path($filename); |
($filename eq 'hosts.tab') || ($filename eq 'domain.tab') || |
my $specifier = basename($filename, ('.tab')); |
($filename eq 'loncapaCAcrl.pem')) { |
my @hosts = (&get_dns_hosts()); |
my ($result,$fh); |
return &push_file($specifier, $pushfile, \@hosts); |
if (!-e $logfile) { |
|
system("touch $logfile"); |
|
system("chown www:www $logfile"); |
|
} |
|
if (open ($fh,'>>',$logfile)) { |
|
print $fh "clusteradmin update started: ".localtime(time)."\n"; |
|
my $pushfile = &construct_table_path($filename); |
|
my @hosts = (&get_dns_hosts()); |
|
my $ext = 'tab'; |
|
if ($filename eq 'loncapaCAcrl.pem') { |
|
$ext = 'pem'; |
|
} |
|
my $specifier = basename($filename, (".$ext")); |
|
my @hosts = (&get_dns_hosts()); |
|
$result = &push_file($specifier, $pushfile, \@hosts, $fh); |
|
print $fh "ended: ".localtime(time)."\n"; |
|
close($fh); |
|
} else { |
|
print STDERR "Could not open $logfile to append. Exiting.\n"; |
|
} |
|
return $result; |
} else { |
} else { |
print STDERR "Only dns_hosts.tab or dns_domain.tab can be updated\n"; |
print STDERR "Only dns_hosts.tab, dns_domain.tab or loncapaCAcrl.pem can be updated\n"; |
&usage(); |
&usage(); |
return 0; |
return 0; |
} |
} |
} |
} |
} |
} |
&define_command("update", \&update_file); |
&define_command("update", \&update_file); |
|
|
|
# |
|
# Checks if current lonHostID is in managers.tab for the cluster, and is in the cluster. |
|
# Parameters: |
|
# args - none |
|
# Returns: |
|
# 1 - lonHostID is is managers.tab |
|
# '' - Failure (printing messages to STDERR). |
|
# |
|
sub is_manager { |
|
my $currhost = $config{'lonHostID'}; |
|
my $canmanage; |
|
if ($currhost eq '') { |
|
print STDERR "Could not determine LON-CAPA host ID\n"; |
|
return; |
|
} elsif (!defined &Apache::lonnet::get_host_ip($currhost)) { |
|
print STDERR "This LON-CAPA host is not part of the cluster.\n"; |
|
} |
|
my $tablename = &construct_table_path('managers.tab'); |
|
if (!open (MANAGERS, $tablename)) { |
|
print STDERR "No managers.tab table. Could not verify host is a manager\n"; |
|
return; |
|
} |
|
while(my $host = <MANAGERS>) { |
|
chomp($host); |
|
next if ($host =~ /^\#/); |
|
if ($host eq $currhost) { |
|
$canmanage = 1; |
|
last; |
|
} |
|
} |
|
close(MANAGERS); |
|
return $canmanage; |
|
} |
#--------------------------------------------------------------------------------- |
#--------------------------------------------------------------------------------- |
# |
# |
# Program entry point. Decode the subcommand from the args array and |
# Program entry point. Decode the subcommand from the args array and |
# dispatch to the appropriate command processor. |
# dispatch to the appropriate command processor. |
# |
# |
|
|
|
if ($< != 0) { # Am I root? |
|
print('You must be root in order to run clusteradmin.'. |
|
"\n"); |
|
exit(-1); |
|
} |
|
|
my $argc = scalar(@ARGV); |
my $argc = scalar(@ARGV); |
if ($argc == 0) { |
if ($argc == 0) { |
print STDERR "Missing subcommand\n"; |
print STDERR "Missing subcommand\n"; |
Line 273 if ($argc == 0) {
|
Line 377 if ($argc == 0) {
|
exit(-1); |
exit(-1); |
} |
} |
|
|
|
if (!&is_manager()) { |
|
print STDERR 'Script needs to be run from a server designated as a "Manager" in the LON-CAPA cluster'."\n"; |
|
exit(-1); |
|
} |
|
|
my $subcommand = shift(@ARGV); # argv now the tail. |
my $subcommand = shift(@ARGV); # argv now the tail. |
|
|
if (!&dispatch_command($subcommand, \@ARGV)) { |
if (!&dispatch_command($subcommand, \@ARGV)) { |