Annotation of loncom/build/CHECKRPMS.default, revision 1.13
1.1 harris41 1: #!/usr/bin/perl
2:
1.2 harris41 3: =pod
4:
5: =head1 NAME
6:
7: B<CHECKRPMS> - automated status report about RPMs on a system
8:
9: =head1 SYNOPSIS
10:
1.7 harris41 11: ./B<CHECKRPMS> [I<modeflag>]
1.2 harris41 12:
13: or
14:
1.7 harris41 15: B<perl> B<CHECKRPMS> [I<modeflag>]
16:
17: If I<modeflag> is left blank, the mode is "interactive". Otherwise,
18: other modes can be specified as shown in the listing below:
19:
20: =over 4
21:
1.8 harris41 22: =item DEFAULT
1.7 harris41 23:
1.8 harris41 24: When left blank, the script runs in interactive mode. First, a proposed
25: list of RPMs is presented to the user. Then, the user is asked if he or
26: she wants to download the RPMs to /tmp/loncapa_rpm_updates/.
1.7 harris41 27:
1.8 harris41 28: =item view
1.2 harris41 29:
1.8 harris41 30: A proposed list of RPMs to update is presented to the user.
1.2 harris41 31:
1.8 harris41 32: =item download
1.2 harris41 33:
1.8 harris41 34: A proposed set of RPMs to update are downloaded into /tmp/loncapa_rpm_updates/.
35: Note that prior information inside /tmp/loncapa_rpm_updates/ is removed.
1.2 harris41 36:
1.8 harris41 37: =item redownload
1.2 harris41 38:
1.8 harris41 39: A proposed set of RPMs to update are downloaded into /tmp/loncapa_rpm_updates/.
40: Note that prior information inside /tmp/loncapa_rpm_updates/ is not removed.
41: (This helps support continual attempts from dialup connections.)
1.2 harris41 42:
1.8 harris41 43: =item html
1.2 harris41 44:
1.8 harris41 45: Similar to view mode. XHTML-formatted output is delivered; presumably
46: to a web client. html mode is automatically chosen if $ENV{'QUERY_STRING'} is
47: defined.
1.2 harris41 48:
1.8 harris41 49: =back
1.2 harris41 50:
1.8 harris41 51: =head1 DESCRIPTION
1.2 harris41 52:
1.8 harris41 53: This file automates the usage of Martin Siegert's "check-rpms"
54: script. It runs through a list of possible mirror sites
55: until it finds one with a reasonably good FTP connection.
1.2 harris41 56:
1.8 harris41 57: For instructions on usage, see L<SYNOPSIS>.
1.2 harris41 58:
59: =head1 AUTHOR
60:
61: Scott Harrison, sharrison@users.sourceforge.net, 2002
62:
63: =cut
64:
1.12 albertel 65: # ' stupid emacs
1.7 harris41 66: # ================================================== READ IN COMMAND ARGUMENTS.
67:
1.4 harris41 68: # ---------------------------------------------------- Process download option.
1.7 harris41 69: my $argument = shift(@ARGV);
70: my $document;
71: my $mode;
72: if ($argument eq '--download' or $argument eq '--redownload')
1.4 harris41 73: {
74: if ($< != 0) # Download mode requires 'root'.
75: {
1.10 harris41 76: print(
1.7 harris41 77: '**** ERROR **** Download mode needs to be run as root'."\n");
78: exit(0); # Exit.
1.4 harris41 79: }
1.7 harris41 80: `rm -Rf /tmp/loncapa_rpm_updates` if $argument eq '--download';
1.4 harris41 81: $download='-v -dl -d /tmp/loncapa_rpm_updates'; # Part of check-rpms args.
1.7 harris41 82: $mode = 'download';
83: }
84: elsif ($argument eq '--view')
85: {
86: $mode = 'view';
87: }
88: elsif ($argument eq '--cronmail')
89: {
90: $mode = 'cronmail';
91: }
92: elsif ($ENV{'QUERY_STRING'} or $argument eq '--html')
93: {
94: $mode = 'html';
1.4 harris41 95: }
96: else
97: {
1.7 harris41 98: $mode = 'interactive';
1.4 harris41 99: }
100:
1.7 harris41 101: # ================================================== GENERAL INITIAL VARIABLES.
102: my $command_name=$0;
103:
1.2 harris41 104: # ---------------- The FTP servers (and their directory paths) to check against
1.5 harris41 105: my @serverpaths_to_try =
106: (
1.9 harris41 107: 'ftpmirror:loncapa@install.lon-capa.org/pub/redhat/linux/updates/',
108: 'mirror.pa.msu.edu/linux/redhat/linux/updates/',
1.7 harris41 109: 'distro.ibiblio.org/pub/linux/distributions/redhat/updates/',
110: 'limestone.uoregon.edu/redhat/updates/',
1.5 harris41 111: 'rufus.w3.org/linux/redhat/linux/updates/',
112: );
1.2 harris41 113:
1.7 harris41 114: # -------------------------------------------- Use check-rpms command this way.
1.5 harris41 115: my $checkcommand = 'check-rpms '.$download.' --rpmuser www -ftp';
1.2 harris41 116:
117: my $FTPSERVER; # ------------------------- the server portion of the serverpath
118: my $FTPUPDATES; # ----------------------------- the actual update root location
119: my @rpms; # ---------------------------------- this will store the list of RPMs
120: my $goodoutput; # ------------------------------------ good stuff was returned!
121: my $reallygoodoutput; # ------------------------------- you are 100% up-to-date
122:
1.7 harris41 123: # ===================================================== Control flow of output.
124: my $out = \*STDOUT; # Default: go to standard output (directly to terminal).
125:
126: if ($mode eq 'cronmail') # If cronmail mode, then save to file.
127: {
128: open(FOUT,'>/tmp/CHECKRPMS.'.$$);
129: $out = \*FOUT;
130: }
131:
132: $| = 1; # Flush to output whenever possible.
133:
134: # ========================================== Variables that must be defineable.
135:
136: # --------------------------------------------------- Determine RedHat version.
137: my $RHversion = (split /\s/, `cat /etc/redhat-release`)[4]; # - 6.2 or 7.3 or ?
138:
139: unless ($RHversion)
140: {
141: terminate($mode,$out,
142: '**** ERROR **** /etc/redhat-release not found'."\n".
143: 'This script does not appear to be running on RedHat.'."\n");
144: }
145:
1.2 harris41 146: # ----------------------------------------- Find the check-rpms script location
1.5 harris41 147: if (-e './check-rpms')
148: {
149: $commandpre='perl ./'; # Use the check-rpms in the current directory.
150: }
151: elsif (-e 'loncom/build/check-rpms')
152: {
1.7 harris41 153: $commandpre='perl loncom/build/'; # Use check-rpms in the loncom/build dir.
154: }
155: elsif (-e '/usr/local/loncapa/bin/check-rpms')
156: {
157: $commandpre='perl /usr/local/loncapa/bin/'; # Use /usr/local dir.
1.5 harris41 158: }
159: else # Cannot find check-rpms, so abort.
160: {
1.7 harris41 161: terminate($mode,$out,
162: '**** ERROR **** CANNOT FIND THE check-rpms SCRIPT'."\n");
1.5 harris41 163: }
1.2 harris41 164:
1.7 harris41 165: # Define check-rpms invocation based on the path to the check-rpms command.
1.5 harris41 166: $checkcommand = $commandpre.$checkcommand;
1.2 harris41 167:
1.7 harris41 168: # ============================================================= Initial output.
169:
170: print($out <<END) if $mode eq 'html';
171: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
172: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
173: <html>
174: <head>
175: <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
176: <title>CHECKRPMS STATUS REPORT</title>
177: </head>
178: <body bgcolor="white">
179: <h1>CHECKRPMS STATUS REPORT</h1>
180: <hr />
181: <pre>
182: END
183:
1.5 harris41 184: # Notify user of current action.
1.7 harris41 185: print($out <<END);
1.2 harris41 186: THIS SCRIPT IS NOW PROBING SEVERAL FTP SERVERS....
187: PLEASE BE PATIENT, THIS MAY TAKE A FEW MINUTES.
188: END
189:
1.7 harris41 190: # ============== Go through all the servers until a decent connection is found.
1.5 harris41 191: SERVERLOOP: foreach my $serverpath (@serverpaths_to_try)
192: {
193: $serverpath=~/^(.*?)\//; # Pattern match the ip name.
194: $FTPSERVER=$1; # Set to the ip name.
1.9 harris41 195: $FTPSERVER_noauth=$FTPSERVER;
196: $FTPSERVER_noauth=~s/^.*?\@//;
197: print($out
198: "Trying $FTPSERVER_noauth...\n"); # Notify of attempts with ip name.
1.13 ! harris41 199: `ping -c 1 -w 10 $FTPSERVER_noauth 2>/dev/null`;#Ping ftp server (u there?)
1.5 harris41 200: if ($?==0) # If the ftp server can be pinged.
201: {
1.7 harris41 202: print($out "$FTPSERVER found...\n"); # Tell user ftp server is found.
1.5 harris41 203: `ncftpls ftp://$FTPSERVER`; # Try to access server with ftp protocol.
204: if ($?==0) # If the ftp server can be accessed with the ftp protocol.
205: {
206: $FTPUPDATES="$serverpath$RHversion/en/os"; # The full update path.
207: # Print the check-rpms command that will be executed.
1.7 harris41 208: print($out $checkcommand.' '.$FTPUPDATES."\n");
209: if ($mode eq 'download') # Was CHECKRPMS run in download mode?
1.5 harris41 210: {
211: $|=1; # Try to send things immediately to stdout; err umm....
212: # Tell the user about the /tmp/loncapa_rpm_updates directory.
1.7 harris41 213: print($out '**** NOTE **** '.
1.5 harris41 214: 'To check the status of the download, you can '.
215: 'periodically inspect the contents of the '.
216: '/tmp/loncapa_rpm_updates directory. '.
217: 'Please be patient; this download may take a while.'.
218: "\n");
219: # Do the download.
1.7 harris41 220: print($out `$checkcommand $FTPUPDATES 2>\&1`);
1.5 harris41 221: # Tell the user about what action they need to take with the
222: # downloaded RPMs.
1.7 harris41 223: print($out
224: 'You may now wish to visit the /tmp/loncapa_rpm_updates'.
1.5 harris41 225: ' directory and upgrade the RPMs. '."\n".
226: 'If this is a critical server (it is currently being'.
227: ' used for classes) and you do not know how to upgrade'.
228: ' RPMs, you should consult someone who has experience '.
229: 'with the "rpm" command.'."\n");
1.7 harris41 230: clean_exit($mode,$out,0); # Assume everything is okay and exit.
1.5 harris41 231: }
232: @rpms=`$checkcommand $FTPUPDATES 2>\&1`; # Read in list of RPMs.
233: # Create a text string that can be pattern matched.
1.2 harris41 234: my $rpmtext=join('',@rpms);
1.5 harris41 235: if ($rpmtext=~/You do not seem to have a/) # No www?
236: {
1.7 harris41 237: print($out "You do not have a 'www' user on your system.\n".
238: "Please add this user and try this command again.\n");
239: clean_exit($mode,$out,0);
1.5 harris41 240: }
241: if ($rpmtext=~/This account is currently not/) # ------------ uh-oh
242: {
1.7 harris41 243: print($out "...strange error, moving on ($FTPSERVER)\n");
1.5 harris41 244: }
245: else # --------------------------------------- the output is "good"
246: {
1.2 harris41 247: $goodoutput=$rpmtext;
1.5 harris41 248: unless (@rpms) # If there are no RPMs to update.
249: {
1.7 harris41 250: $reallygoodoutput = <<END;
1.2 harris41 251: **** NOTE **** All RPMS on your system appear to be up to date.
252: END
1.7 harris41 253: $goodoutput = ' ';
1.5 harris41 254: }
1.2 harris41 255: last SERVERLOOP;
1.5 harris41 256: }
257: }
1.7 harris41 258: print($out '...cannot establish an ftp session with '.$FTPSERVER."\n");
1.5 harris41 259: }
260: else
261: {
1.7 harris41 262: print($out "...cannot find $FTPSERVER on the network\n");
1.5 harris41 263: }
264: }
265: if (!$goodoutput) # If never received any useable output, assume "no server".
266: {
1.7 harris41 267: print($out '**** ERROR **** Cannot find a working ftp server.'."\n");
268: clean_exit($mode,$out,0);
1.5 harris41 269: }
270: elsif ($reallygoodoutput) # Everything is peachy keen and up-to-date already.
271: {
1.7 harris41 272: print($out $reallygoodoutput);
1.5 harris41 273: }
274: else # There are RPMs that need to be updated; show list to user.
275: {
276: my $rpmcount=scalar(@rpms); # Count up size of RPM list.
1.7 harris41 277: print($out <<END); # Print out an advisory warning to user.
1.4 harris41 278: **** WARNING **** You need to update at least $rpmcount RPMS shown in
1.1 harris41 279: the list below. THIS IS IMPORTANT FOR SECURITY.
280:
281: END
1.7 harris41 282: print($out $goodoutput); # Output the RPM list.
283: if ($mode eq 'interactive')
284: {
285: print($out <<END);
286: Do you want to download the RPMs listed above (y/n)?
287: END
288: my $in=<>;
289: if ($in=~/^y/)
290: {
291: print($out 'Please be patient... downloading into '.
292: '/tmp/loncapa_rpm_updates'."\n");
293: print($out `perl $command_name --download`);
294: clean_exit($mode,$out,0);
295: }
296: }
297: print($out <<END); # Output instructions to user about taking action.
1.1 harris41 298:
299: Please visit ftp://$FTPUPDATES
300: and download the RPMS you need.
301: For instructions on working with (and upgrading) RPMS, please
302: visit http://www.rpm.org/max-rpm/.
1.4 harris41 303: To automatically download these RPMs to /tmp/loncapa_rpm_updates/,
304: run the CHECKRPMS command as "./CHECKRPMS --download"
1.1 harris41 305: END
1.7 harris41 306: if ($mode eq 'cronmail')
307: {
308: print($out <<END); # Output more instructions to user.
309: CHECKRPMS should be located in /usr/local/loncapa/bin/.
310: END
311: }
312: }
313:
314: clean_exit($mode,$out,0);
315:
316: # ================================================================ Subroutines.
317:
318: sub clean_exit
319: {
320: my ($mode,$out,$code)=@_;
321:
322: if ($mode eq 'cronmail') # If cronmail mode, then mail LON-CAPA sys admin.
323: {
324: close(FOUT);
1.11 harris41 325:
1.7 harris41 326: # Read in configuration to get e-mail addresses.
327: my $perlvarref = read_conf('loncapa.conf');
328: my %perlvar = %{$perlvarref};
329: undef $perlvarref;
330: delete $perlvar{'lonReceipt'}; # remove since sensitive
331: delete $perlvar{'lonSqlAccess'}; # remove since sensitive
332:
333: # Set metadata for the e-mail.
334: my $emailto = "$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";
1.11 harris41 335:
336: my $subj=$perlvar{'lonHostID'}.', RPMS to upgrade';
337:
338: # Make the e-mail's subject header to describe whether up-to-date.
339: if ($reallygoodoutput)
340: {
341: $subj = 'happy_lon: '.$subj; # Machine is up-to-date.
342: }
343: else
344: {
345: $subj = 'ALERT_lon: '.$subj; # There are out-of-date RPMs.
346: }
347:
348: # Send the e-mail.
1.12 albertel 349: if (!$reallygoodoutput)
350: {
351: system(
352: 'metasend -b -t '.$emailto.' -s '.
353: "'$subj' -f /tmp/CHECKRPMS.$$ -m text/plain");
354: }
1.7 harris41 355: }
356:
357: print($out <<END) if $mode eq 'html'; # If html mode, print ending tags.
358: </pre>
359: </body>
360: </html>
361: END
362: exit($code);
1.5 harris41 363: }
1.7 harris41 364:
365: sub terminate
366: {
367: my ($mode,$out,$output);
368: if ($mode eq 'html')
369: {
370: print($out <<END);
371: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
372: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
373: <html>
374: <head>
375: <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
376: <title>CHECKRPMS ERROR</title>
377: </head>
378: <body bgcolor="white">
379: <h1>CHECKRPMS ERROR</h1>
380: <hr />
381: <p><font color="red"><font size="+1">
382: END
383: }
384: print($out $output);
385: if ($mode eq 'html')
386: {
387: print($out <<END);
388: </font></font></p></body></html>
389: END
390: }
391: }
392:
393:
394: # - read_conf: read LON-CAPA server configuration, especially PerlSetVar values
395: sub read_conf
396: {
397: my (@conf_files)=@_;
398: my %perlvar;
399: my $confdir='/etc/httpd/conf/';
400: foreach my $filename (@conf_files,'loncapa_apache.conf')
401: {
402: open(CONFIG,'<'.$confdir.$filename) or
403: die("Can't read $confdir$filename");
404: while (my $configline=<CONFIG>)
405: {
406: if ($configline =~ /^[^\#]*PerlSetVar/)
407: {
408: my ($unused,$varname,$varvalue)=split(/\s+/,$configline);
409: chomp($varvalue);
410: $perlvar{$varname}=$varvalue;
411: }
412: }
413: close(CONFIG);
414: }
415: my $perlvarref=\%perlvar;
416: return ($perlvarref);
417: }
418:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>