File:  [LON-CAPA] / loncom / build / Attic / CHECKRPMS.default
Revision 1.7: download - view: text, annotated - select for diffs
Mon Sep 9 15:04:48 2002 UTC (21 years, 10 months ago) by harris41
Branches: MAIN
CVS tags: HEAD
BUG 718 FIX; BUG 730 FIX; BUG 731 FIX
cronmail mode supported; html output mode supported; view mode supported;
interactive mode supported (view then ask if user wants to download);
download mode supported; redownload mode supported (for dialup connections)

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>