--- loncom/clusteradmin 2009/03/16 09:43:00 1.2 +++ loncom/clusteradmin 2011/05/16 15:48:26 1.5 @@ -8,7 +8,7 @@ =head1 DESCRIPTION -Performs an adiminstrative action on all hosts in the current dns_hosts.tab +Performs an adminstrative action on DNS hosts in the current hosts.tab file. 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. @@ -16,7 +16,7 @@ Furthermore, lonc must be running on thi 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 the147 host we want to talk with +they will eventually happen even if the host we want to talk with is dead. @@ -152,6 +152,7 @@ sub usage { my $config_vars = LONCAPA::Configuration::read_conf('loncapa.conf'); my %config = %{$config_vars}; +my $logfile = $config{'lonDaemons'}.'/logs/dns_updates.log'; sub construct_table_path { @@ -175,9 +176,9 @@ sub get_dns_hosts() while (my $line = ) { chomp($line); if ($line =~ /^\^/) { - $line =~ s/^\^//; # Get rid of leading ^ - $line =~ s/\s*$//; # and any trailing whitespace. - push(@result, $line); + if ($line =~ /^\^([\w.\-]+)/) { + push(@result,$1); + } } } return (@result); @@ -198,7 +199,7 @@ sub get_dns_hosts() # 0 - Failure with appropriate output to stderr. # sub push_file { - my ($specifier, $pushfile, $hosts) = @_; + my ($specifier, $pushfile, $hosts, $fh) = @_; # Read in the entire file: @@ -217,14 +218,21 @@ sub push_file { # Iterate over the hosts and run cmd as a critical # operation: + my @ids=&Apache::lonnet::current_machine_ids(); foreach my $host (@$hosts) { 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); - if ($reply ne 'ok') { - print STDERR "Reply from $host ($loncapa_name) not 'ok' was: $reply\n"; - } + my $msg; + 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; } # @@ -247,11 +255,25 @@ sub update_file { # 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); + if (($filename eq 'dns_hosts.tab') || ($filename eq 'dns_domain.tab') || + ($filename eq 'hosts.tab') || ($filename eq 'domain.tab')) { + my ($result,$fh); + 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 $specifier = basename($filename, ('.tab')); + 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 { print STDERR "Only dns_hosts.tab or dns_domain.tab can be updated\n"; &usage(); @@ -260,12 +282,52 @@ sub 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 = ) { + 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 # 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); if ($argc == 0) { print STDERR "Missing subcommand\n"; @@ -273,6 +335,11 @@ if ($argc == 0) { 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. if (!&dispatch_command($subcommand, \@ARGV)) {