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