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