Annotation of loncom/lonManage, revision 1.11
1.1 foxr 1: #!/usr/bin/perl
2: # The LearningOnline Network with CAPA
3: #
4: # lonManage supports remote management of nodes in a LonCAPA cluster.
5: #
1.11 ! foxr 6: # $Id: lonManage,v 1.10 2003/08/18 10:43:31 foxr Exp $
1.1 foxr 7: #
1.11 ! foxr 8: # $Id: lonManage,v 1.10 2003/08/18 10:43:31 foxr Exp $
1.1 foxr 9: #
10: # Copyright Michigan State University Board of Trustees
11: #
12: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
13: ## LON-CAPA is free software; you can redistribute it and/or modify
14: # it under the terms of the GNU General Public License as published by
15: # the Free Software Foundation; either version 2 of the License, or
16: # (at your option) any later version.
17: #
18: # LON-CAPA is distributed in the hope that it will be useful,
19: # but WITHOUT ANY WARRANTY; without even the implied warranty of
20: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: # GNU General Public License for more details.
22: #
23: # You should have received a copy of the GNU General Public License
24: # along with LON-CAPA; if not, write to the Free Software
25: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26: #
27: # /home/httpd/html/adm/gpl.txt
28: #
29: # http://www.lon-capa.org/
30: #
31: #
32: # lonManage supports management of remot nodes in a lonCAPA cluster.
33: # it is a command line tool. The following command line syntax (usage)
34: # is supported:
35: #
36: # lonManage -push <tablename> newfile host
37: # Push <tablename> to the lonTabs directory. Note that
38: # <tablename> must be one of:
39: # hosts (hosts.tab)
40: # domain (domain.tab)
41: #
42: # lonManage -reinit lonc host
43: # Sends a HUP signal to the remote systems's lond.
44: #
45: # lonmanage -reinit lond host
46: # Requests the remote system's lond perform the same action as if
47: # it had received a HUP signal.
48: #
49: # In the above syntax, the host above is the hosts.tab name of a host,
50: # not the IP address of the host.
51: #
1.3 foxr 52: # $Log: lonManage,v $
1.11 ! foxr 53: # Revision 1.10 2003/08/18 10:43:31 foxr
! 54: # Code/test ValidHost. The hosts.tab and the perl variables are read in as
! 55: # global hashes as a side effect. May later want to clean this up by making
! 56: # a separate getconfig function and hoisting the config reads into that.
! 57: #
1.10 foxr 58: # Revision 1.9 2003/08/18 10:25:46 foxr
59: # Write ReinitProcess function in terms of ValidHost and Transact.
60: #
1.9 foxr 61: # Revision 1.8 2003/08/18 10:18:21 foxr
62: # Completed PushFile function in terms of
63: # - ValidHost - Determines if target host is valid.
64: # - Transact - Performs one of the valid transactions with the
65: # appropriate lonc<-->lond client/server pairs.
66: #
1.8 foxr 67: # Revision 1.7 2003/08/18 09:56:01 foxr
68: # 1. Require to be run as root.
69: # 2. Catch case where no operation switch is supplied and put out usage.
70: # 3. skeleton/comments for PushFile function.
71: #
1.7 foxr 72: # Revision 1.6 2003/08/12 11:02:59 foxr
73: # Implement command switch dispatching.
74: #
1.6 foxr 75: # Revision 1.5 2003/08/12 10:55:42 foxr
76: # Complete command line parsing (tested)
77: #
1.5 foxr 78: # Revision 1.4 2003/08/12 10:40:44 foxr
79: # Get switch parsing right.
80: #
1.4 foxr 81: # Revision 1.3 2003/08/12 10:22:35 foxr
82: # Put in parameter parsing infrastructure
83: #
1.3 foxr 84: # Revision 1.2 2003/08/12 09:58:49 foxr
85: # Add usage and skeleton documentation.
1.2 foxr 86: #
1.3 foxr 87: #
1.10 foxr 88:
89: # Modules required:
90:
1.7 foxr 91: use strict; # Because it's good practice.
92: use English; # Cause I like meaningful names.
1.3 foxr 93: use Getopt::Long;
1.10 foxr 94: use LONCAPA::Configuration; # To handle configuration I/O.
95:
96: # File scoped variables:
97:
98: my %perlvar; # Perl variable defs from apache config.
99: my %hostshash; # Host table as a host indexed hash.
1.2 foxr 100:
1.3 foxr 101: sub Usage {
1.2 foxr 102: print "Usage:";
103: print <<USAGE;
1.3 foxr 104: lonManage --push=<tablename> newfile host
1.2 foxr 105: Push <tablename> to the lonTabs directory. Note that
106: <tablename> must be one of:
107: hosts (hosts.tab)
108: domain (domain.tab)
109:
1.3 foxr 110: lonManage --reinit=lonc host
1.2 foxr 111: Sends a HUP signal to the remote systems's lond.
112:
1.7 foxr 113: lonManage --reinit=lond host
1.2 foxr 114: Requests the remote system's lond perform the same action as if
115: it had received a HUP signal.
116:
117: In the above syntax, the host above is the hosts.tab name of a host,
118: not the IP address of the host.
119: USAGE
120:
121:
122: }
123:
124: #
1.3 foxr 125: # Use Getopt::Long to parse the parameters of the program.
126: #
127: # Return value is a list consisting of:
128: # A 'command' which is one of:
129: # push - table push requested.
130: # reinit - reinit requested.
131: # Additional parameters as follows:
132: # for push: Tablename, hostname
133: # for reinit: Appname hostname
134: #
135: # This function does not validation of the parameters of push and
136: # reinit.
1.4 foxr 137: #
138: # returns a list. The first element of the list is the operation name
139: # (e.g. reinit or push). The second element is the switch parameter.
140: # for push, this is the table name, for reinit, this is the process name.
141: # Additional elements of the list are the command argument. The count of
142: # command arguments is validated, but not their semantics.
143: #
1.3 foxr 144: # returns an empty list if the parse fails.
145: #
146:
147: sub ParseArgs {
1.4 foxr 148: my $pushing = '';
1.7 foxr 149: my $reinitting = '';
1.5 foxr 150:
1.4 foxr 151: if(!GetOptions('push=s' => \$pushing,
152: 'reinit=s' => \$reinitting)) {
153: return ();
154: }
155:
156: # Require exactly one of --push and --reinit
157:
1.5 foxr 158: my $command = '';
1.4 foxr 159: my $commandarg = '';
1.5 foxr 160: my $paramcount = @ARGV; # Number of additional arguments.
161:
162:
1.4 foxr 163: if($pushing ne '') {
1.5 foxr 164:
165: # --push takes in addition a table, and a host:
166: #
167: if($paramcount != 2) {
168: return (); # Invalid parameter count.
169: }
1.4 foxr 170: if($command ne '') {
171: return ();
172: } else {
1.5 foxr 173:
1.4 foxr 174: $command = 'push';
175: $commandarg = $pushing;
176: }
177: }
1.5 foxr 178:
1.4 foxr 179: if ($reinitting ne '') {
1.5 foxr 180:
181: # --reinit takes in addition just a host name
182:
183: if($paramcount != 1) {
184: return ();
185: }
1.4 foxr 186: if($command ne '') {
187: return ();
188: } else {
189: $command = 'reinit';
190: $commandarg = $reinitting;
191: }
192: }
193:
1.5 foxr 194: # Build the result list:
195:
196: my @result = ($command, $commandarg);
197: my $i;
198: for($i = 0; $i < $paramcount; $i++) {
199: push(@result, $ARGV[$i]);
200: }
201:
202: return @result;
1.3 foxr 203: }
1.10 foxr 204: #
1.11 ! foxr 205: # Read the loncapa configuration stuff.
! 206: #
! 207: sub ReadConfig {
! 208: my $perlvarref = LONCAPA::Configuration::read_conf('loncapa.conf');
! 209: %perlvar = %{$perlvarref};
! 210: my $hoststab = LONCAPA::Configuration::read_hosts(
! 211: "$perlvar{'lonTabDir'}/hosts.tab");
! 212: %hostshash = %{$hoststab};
! 213:
! 214: }
! 215: #
1.10 foxr 216: # Determine if the target host is valid.
217: # This is done by reading the current hosts.tab file.
218: # For the host to be valid, it must be inthe file.
219: #
220: # Parameters:
221: # host - Name of host to check on.
222: # Returns:
223: # true if host is valid.
224: # false if host is invalid.
225: #
1.8 foxr 226: sub ValidHost {
1.10 foxr 227: my $host = shift;
1.11 ! foxr 228:
! 229: ReadConfig;
1.10 foxr 230:
231: return defined $hostshash{$host};
232:
1.8 foxr 233: }
234: sub Transact {
1.10 foxr 235:
1.8 foxr 236: }
1.7 foxr 237: #
238: # Called to push a file to the remote system.
239: # The only legal files to push are hosts.tab and domain.tab.
240: # Security is somewhat improved by
241: #
242: # - Requiring the user run as root.
243: # - Connecting with lonc rather than lond directly ensuring this is a loncapa
244: # host
245: # - We must appear in the remote host's hosts.tab file.
246: # - The host must appear in our hosts.tab file.
247: #
248: # Parameters:
249: # tablename - must be one of hosts or domain.
250: # tablefile - name of the file containing the table to push.
251: # host - name of the host to push this file to.
252: #
253: sub PushFile {
254: my $tablename = shift;
255: my $tablefile = shift;
256: my $host = shift;
257:
1.8 foxr 258: # Open the table file:
259:
260: if(!open(TABLEFILE, "<$tablefile")) {
261: die "ENOENT - No such file or directory $tablefile";
262: }
263:
264: # Require that the host be valid:
265:
266: if(!ValidHost($host)) {
267: die "EHOSTINVAL - Invalid host $host"; # Ok so I invented this 'errno'.
268: }
269: # Read in the file. If the table name is valid, push it.
270:
271: my @table = <TABLEFILE>; # These files are pretty small.
272: close TABLEFILE;
273:
274: if( ($tablename eq "host") ||
275: ($tablename eq "domain")) {
276: Transact($host, "pushfile:$tablename:",\@table);
277: } else {
278: die "EINVAL - Invalid parameter. tablename: $tablename must be host or domain";
279: }
1.7 foxr 280: }
1.9 foxr 281: #
282: # This function is called to reinitialize a server in a remote host.
283: # The servers that can be reinitialized are:
284: # - lonc - The lonc client process.
285: # - lond - The lond daemon.
286: # NOTE:
287: # Reinitialization in this case means re-scanning the hosts table,
288: # starting new lond/lonc's as approprate and stopping existing lonc/lond's.
289: #
290: # Parameters:
291: # process - The name of the process to reinit (lonc or lond).
292: # host - The host in which this reinit will happen.
293: #
294: sub ReinitProcess {
295: my $process = shift;
296: my $host = shift;
1.3 foxr 297:
1.9 foxr 298: # Ensure the host is valid:
299:
300: if(!ValidHost($host)) {
301: die "EHOSTINVAL - Invalid host $host";
302: }
303: # Ensure target process selector is valid:
304:
305: if(($process eq "lonc") ||
306: ($process eq "lond")) {
307: Transact($host, "reinit:$process");
308: } else {
309: die "EINVAL -Invalid parameter. Process $process must be lonc or lond";
310: }
1.7 foxr 311: }
1.6 foxr 312: #--------------------------- Entry point: --------------------------
313:
314: # Parse the parameters
315: # If command parsing failed, then print usage:
1.2 foxr 316:
1.7 foxr 317: my @params = ParseArgs;
318: my $nparam = @params;
1.3 foxr 319:
320: if($nparam == 0) {
1.2 foxr 321: Usage;
1.4 foxr 322: exit -1;
1.2 foxr 323: }
1.7 foxr 324: #
325: # Next, ensure we are running as EID root.
326: #
327: if ($EUID != 0) {
328: die "ENOPRIV - No privilege for requested operation"
1.6 foxr 329: }
330:
1.4 foxr 331:
1.6 foxr 332: # Based on the operation requested invoke the appropriate function:
333:
1.7 foxr 334: my $operation = shift @params;
1.6 foxr 335:
336: if($operation eq "push") { # push tablename filename host
1.7 foxr 337: my $tablename = shift @params;
338: my $tablefile = shift @params;
339: my $host = shift @params;
1.6 foxr 340: PushFile($tablename, $tablefile, $host);
341:
1.7 foxr 342: } elsif($operation eq "reinit") { # reinit processname host.
343: my $process = shift @params;
344: my $host = shift @params;
345: ReinitProcess($process, $host);
1.6 foxr 346: }
1.7 foxr 347: else {
348: Usage;
1.6 foxr 349: }
1.4 foxr 350: exit 0;
1.2 foxr 351:
352: =head1 NAME
353: lonManage - Command line utility for remote management of lonCAPA
354: cluster nodes.
355:
356: =head1 SYNOPSIS
357:
358: Usage:
1.3 foxr 359: B<lonManage --push=<tablename> newfile host>
1.2 foxr 360: Push <tablename> to the lonTabs directory. Note that
361: <tablename> must be one of:
362: hosts (hosts.tab)
363: domain (domain.tab)
364:
1.3 foxr 365: B<lonManage --reinit=lonc host>
1.2 foxr 366: Sends a HUP signal to the remote systems's lond.
367:
1.3 foxr 368: B<lonmanage --reinit=lond host>
1.2 foxr 369: Requests the remote system's lond perform the same action as if
370: it had received a HUP signal.
371:
372: In the above syntax, the host above is the hosts.tab name of a host,
373: not the IP address of the host.
374:
375:
376: =head1 DESCRIPTION
377:
378: =head1 PREREQUISITES
1.3 foxr 379:
1.7 foxr 380: =item strict
1.3 foxr 381: =item Getopt::Long
1.7 foxr 382: =item English
1.2 foxr 383:
384: =head1 CATEGORIES
385: Command line utility
386:
387: =cut
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>