Annotation of loncom/build/CHECKRPMS, revision 1.11

1.11    ! raeburn     1: #!/usr/bin/perl
1.1       raeburn     2: #
                      3: # The LearningOnline Network with CAPA
                      4: # Checks status of RPM packages on system.
                      5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
                     28: 
                     29: =pod
                     30: 
                     31: =head1 NAME
                     32: 
1.11    ! raeburn    33: B<CHECKRPMS> - automated status report about RPMs (RHEL/Fedora/CentOS/SuSE) 
        !            34:                or debs (Debian/Ubuntu) on a system. 
1.1       raeburn    35: 
                     36: =head1 DESCRIPTION
                     37: 
                     38: This file automates the process of checking for available updates
                     39: to LON-CAPA systems. distprobe is used to determine the Linux distribution.
                     40: 
                     41: The utility which is used to complete the check depends on the distro:
                     42: 
1.8       raeburn    43: fedora, rhel 5/5+, centos, scientific - yum
1.1       raeburn    44: suse 9.X and sles9 - you
1.11    ! raeburn    45: suse 10.2,10.3,11.1 - zypper 
1.9       raeburn    46: sles10,suse10.1 - rug
1.1       raeburn    47: rhel 4 - up2date
1.11    ! raeburn    48: debian, ubuntu - apt-get
1.1       raeburn    49: others - check-rpms
                     50: 
                     51: Created by amalgamating previous distribution-specific CHECKRPMS.dist files (where dist was one of: fedora, rhel, suse, sles10, default).
                     52: 
                     53: Must be run as root or www.
                     54: 
                     55: =cut
                     56: 
                     57: use strict;
                     58: use lib '/home/httpd/lib/perl/';
                     59: use LONCAPA::Configuration;
1.10      raeburn    60: use Apache::loncommon();
1.1       raeburn    61: 
                     62: my $tmpfile = '/tmp/CHECKRPMS.'.$$;
                     63: my $perlvar= LONCAPA::Configuration::read_conf('loncapa.conf');
                     64: 
                     65: # Determine who we email
1.10      raeburn    66: my $defdom = $perlvar->{'lonDefDomain'};
                     67: my $origmail = $perlvar->{'lonAdmEMail'};
                     68: my $emailto = &Apache::loncommon::build_recipient_list(undef,
                     69:                                    'packagesmail',$defdom,$origmail);
1.1       raeburn    70: my $subj = $perlvar->{'lonHostID'};
                     71: 
                     72: # Get Linux distro
                     73: open(PIPE, "$perlvar->{'lonDaemons'}/distprobe |");
                     74: my $distro = <PIPE>;
                     75: close(PIPE);
                     76: 
                     77: undef($perlvar);
                     78: 
                     79: my $hostname = `hostname`;
                     80: chomp($hostname);
                     81: open(TMPFILE,">$tmpfile");
                     82: print TMPFILE localtime(time).'    '.$hostname."\n";
                     83: close(TMPFILE);
                     84: 
                     85: my ($cmd,$send,$addsubj);
                     86: if ($distro =~ /^fedora\d+$/) {
                     87:     $cmd = 'yum update';
                     88:     &prepare_msg($tmpfile,$cmd);
                     89:     ($send,$addsubj) = &check_with_yum($tmpfile);
1.6       albertel   90: } elsif ($distro =~ /^(suse|sles)9\.?\d?$/) {
1.1       raeburn    91:     $cmd = 'you';
                     92:     &prepare_msg($tmpfile,$cmd);
                     93:     ($send,$addsubj) = &check_with_you($tmpfile);
1.11    ! raeburn    94: } elsif ($distro =~ /^suse(\d{2,})\.(\d+)$/) {
1.9       raeburn    95:     my $version =$1;
1.11    ! raeburn    96:     my $subversion = $2;
        !            97:     if (($version > 10) || (($version == 10) && ($subversion > 1))) { 
1.9       raeburn    98:         $cmd = 'zypper up';
                     99:         &prepare_msg($tmpfile,$cmd);
                    100:         ($send,$addsubj) = &check_with_zypper($tmpfile);
                    101:     } else {
                    102:         $cmd = 'rug up';
                    103:         &prepare_msg($tmpfile,$cmd);
                    104:         ($send,$addsubj) = &check_with_rug($tmpfile);
                    105:     }
                    106: } elsif ($distro =~ /^sles10$/) {
1.1       raeburn   107:     $cmd = 'rug up';
                    108:     &prepare_msg($tmpfile,$cmd);
                    109:     ($send,$addsubj) = &check_with_rug($tmpfile);
1.7       raeburn   110: } elsif ($distro =~ /^rhes(\d+)$/) {
                    111:     my $version = $1;
                    112:     if ($version == 4) {
                    113:         $cmd ='up2date -u --nox';
                    114:         &prepare_msg($tmpfile,$cmd);
                    115:         ($send,$addsubj) = &check_with_up2date($tmpfile);
                    116:     } elsif ($version > 4) {
                    117:         $cmd = 'yum update';
                    118:         &prepare_msg($tmpfile,$cmd);
                    119:         ($send,$addsubj) = &check_with_yum($tmpfile);
                    120:     }
1.8       raeburn   121: } elsif ($distro =~ /^centos\d+$/) {
                    122:     $cmd = 'yum update';
                    123:     &prepare_msg($tmpfile,$cmd);
                    124:     ($send,$addsubj) = &check_with_yum($tmpfile);
                    125: } elsif ($distro =~ /^scientific\d+\.\d$/) {
                    126:     $cmd = 'yum update';
                    127:     &prepare_msg($tmpfile,$cmd);
                    128:     ($send,$addsubj) = &check_with_yum($tmpfile);
1.11    ! raeburn   129: } elsif ($distro =~ /^(debian|ubuntu)\d+/) {
        !           130:     $cmd = 'apt-get upgrade';
        !           131:     &prepare_msg($tmpfile,$cmd);
        !           132:     ($send,$addsubj) = &check_with_apt($tmpfile);
1.1       raeburn   133: } else {
                    134:     $cmd = '/usr/local/bin/check-rpms --update';
                    135:     ($send,$addsubj) = &check_with_checkrpms($tmpfile);
                    136: }
                    137: if ($send) {
                    138:     $subj .= $addsubj;
1.10      raeburn   139:     system(qq{mail -s '$subj' "$emailto" < $tmpfile});
1.1       raeburn   140: }
                    141: 
                    142: sub prepare_msg {
                    143:     my ($tmpfile,$cmd) = @_;
                    144:     #
                    145:     # Put some nice text in $tmpfile
                    146:     open(TMPFILE,">>$tmpfile");
                    147:     print TMPFILE <<ENDHEADER;
                    148: Your system needs to be updated.  Please execute (as root)
                    149: 
                    150: $cmd
                    151: 
                    152: to bring it up to date.
                    153: 
1.5       raeburn   154: This is very important for the security of your server.  The packages which need to be updated are listed below.
1.1       raeburn   155: 
                    156: ENDHEADER
                    157:     close(TMPFILE);
                    158:     return;
                    159: }
                    160: 
                    161: sub check_with_you {
                    162:     my ($tmpfile) =@_;
                    163:     my $you = '/usr/bin/online_update';
                    164:     my $sendflag = 0;
                    165:     my $append_to_subj;
                    166: 
1.5       raeburn   167:     if (open (PIPE, "$you -k -len 2>&1 |")) {
1.1       raeburn   168:         my $output=<PIPE>;
                    169:         close(PIPE);
                    170:         chomp $output;
                    171:         unless ($output eq 'No updates available.') {
1.5       raeburn   172:             if (open (PIPE, "$you -s -d -len |grep ^INSTALL |")) {
                    173:                 my @updates = <PIPE>;
                    174:                 close(PIPE);
                    175:                 my $allpackages;
                    176:                 foreach my $line (@updates) {
                    177:                     my $package = substr($line,rindex($line,'/')+1);
                    178:                     if ($package ne '') {
                    179:                         $allpackages .= $package;
                    180:                     }
                    181:                 }
                    182:                 if ($allpackages ne '') {
                    183:                     open(TMPFILE,">>$tmpfile");
                    184:                     print TMPFILE $allpackages;
                    185:                     close(TMPFILE);
                    186:                     $sendflag = 1;
                    187:                     $append_to_subj = ' RPMS to upgrade';
                    188:                 }
                    189:             } else {
                    190:                 $sendflag = 1;
                    191:                 $append_to_subj = ' Error running RPM update script';
                    192:             }
1.1       raeburn   193:         }
                    194:     } else {
                    195:         $sendflag = 1;
                    196:         $append_to_subj = ' Error running RPM update script';
                    197:     }
                    198:     return ($sendflag,$append_to_subj);
                    199: }
                    200: 
                    201: sub check_with_yum {
                    202:     my ($tmpfile) = @_;
                    203:     my $yum = '/usr/bin/yum';
                    204:     my $sendflag = 0;
                    205:     my $append_to_subj;
                    206: 
                    207:     #
                    208:     # Execute yum command
                    209:     my $command = $yum.' check-update '.'>>'.$tmpfile;
                    210:     system($command);
                    211: 
                    212:     my $returnvalue = $?>>8;
                    213: 
                    214:     #
                    215:     # Determine status of yum run
                    216:     if (100 == $returnvalue) {
                    217:         $sendflag = 1;
                    218:         $append_to_subj = ' RPMS to upgrade';
                    219:     } elsif (0 != $returnvalue) {
                    220:         $sendflag = 1;
                    221:         $append_to_subj = ' Error running RPM update script';
                    222:     } else {
                    223:         # yum returned 0, so everything is up to date.
                    224:     }
                    225:     return ($sendflag,$append_to_subj);
                    226: }
                    227: 
                    228: sub check_with_up2date {
                    229:     my ($tmpfile) = @_;
                    230:     my $up2date = '/usr/bin/up2date-nox';
                    231:     my $sendflag = 0;
                    232:     my $append_to_subj;
                    233:     #
                    234:     # Execute online_update command to check for updates
                    235:     my $up2date_error = 1;
                    236:     if (open (PIPE, "$up2date -l 2>&1 |")) {
                    237:         my @result=<PIPE>;
                    238:         close(PIPE);
1.4       raeburn   239:         my $output; 
                    240:         foreach my $line (@result) {
                    241:             if ($line =~ /^The following Packages were marked to be skipped by your configuration:/) {
                    242:                 last;
                    243:             } else {
                    244:                 $output .= $line;
                    245:             }
                    246:         } 
1.1       raeburn   247:         if (@result > 0) {
                    248:             if ($output =~ /Fetching Obsoletes list/) {
                    249:                 $up2date_error = 0;
                    250:                 if ($output =~ /Name\s+Version\s+Rel\s+[\n\r\f]+\-+[\n\r\f]+(.+)/s) {
                    251:                     my $packagelist = $1;
1.4       raeburn   252:                     if ($packagelist ne '' && $packagelist !~ /^[\s\n\r\f]+$/) {
1.1       raeburn   253:                         open(TMPFILE,">>$tmpfile");
                    254:                         print TMPFILE $packagelist;
                    255:                         close(TMPFILE);
                    256:                         $append_to_subj = ' RPMS to upgrade';
                    257:                         $sendflag = 1;
                    258:                     }
                    259:                 }
                    260:             }
                    261:         }
                    262:     }
                    263:     if ($up2date_error) {
                    264:         $append_to_subj = ' Error running RPM update script';
                    265:         $sendflag = 1;
                    266:     }
                    267:     return ($sendflag,$append_to_subj);
                    268: }
                    269: 
                    270: sub check_with_rug {
                    271:     my ($tmpfile) = @_;
                    272:     my $rug = '/usr/bin/rug';
                    273:     my $sendflag = 0;
                    274:     my $append_to_subj;
                    275:     #
                    276:     # Execute rug command to check for updates
                    277:     if (open (PIPE, "$rug up -N 2>&1 |")) {
                    278:         my @output=<PIPE>;
                    279:         close(PIPE);
                    280:         chomp(@output);
                    281:         my @clean_output;
                    282:         foreach my $line (@output) {
1.3       raeburn   283:             if ($line =~ /^Waking\sup\sZMD\.\.\./) {
1.1       raeburn   284:                 next;
1.2       raeburn   285:             } elsif ($line eq 'Done') {
                    286:                 next;
                    287:             } elsif ($line eq '') {
                    288:                 next;
                    289:             } elsif ($line eq 'The following packages will be installed:') {
                    290:                 next;
                    291:             } elsif ($line eq 'Resolving Dependencies...') {
                    292:                 next;
                    293:             } elsif ($line eq 'Transaction...') {
                    294:                 last;
                    295:             } elsif ($line eq 'No updates are available.') {
1.1       raeburn   296:                 last;
1.5       raeburn   297:             } elsif ($line eq 'Downloading Packages...') {
                    298:                 last;
1.1       raeburn   299:             } else {
                    300:                 push(@clean_output,$line);
                    301:             }
                    302:         }
                    303:         if (@clean_output > 0) {
                    304:             open(TMPFILE,">>$tmpfile");
                    305:             print TMPFILE join("\n",@clean_output);
                    306:             close(TMPFILE);
                    307:             $append_to_subj= ' RPMS to upgrade';
                    308:             $sendflag = 1;
                    309:          }
                    310:     } else {
                    311:         $append_to_subj = ' Error running RPM update check';
                    312:         $sendflag = 1;
                    313:     }
                    314:     return ($sendflag,$append_to_subj);
                    315: }
                    316: 
1.9       raeburn   317: sub check_with_zypper {
                    318:     my ($tmpfile) = @_;
                    319:     my $zypper = '/usr/bin/zypper';
                    320:     my $sendflag = 0;
                    321:     my $append_to_subj;
                    322:     my $header;
                    323:     #
                    324:     # Execute zypper command to check for updates
                    325:     if (open (PIPE, "$zypper lu 2>&1 |")) {
                    326:         my @output=<PIPE>;
                    327:         close(PIPE);
                    328:         chomp(@output);
                    329:         my @clean_output;
                    330:         foreach my $line (@output) {
                    331:             if ($line eq 'Restoring system sources...') {
                    332:                 next;
                    333:             } elsif ($line =~ /^Parsing\smetadata\sfor\s/) {
                    334:                 next;
                    335:             } elsif ($line eq 'Parsing RPM database...') {
                    336:                 next;
                    337:             } elsif ($line  =~ /^Catalog\s+\|\s+Name\s+\|\s+Version\s+\|\s+Category\s+\|\s+Status$/) {
                    338:                 $header = $line."\n";
                    339:                 next;
                    340:             } elsif ($line =~ /^[-+]+$/) {
                    341:                 $header .= $line."\n";
                    342:                 next;
                    343:             } elsif ($line eq 'WARNING: These are only the updates affecting the updater itself.') {
                    344:                 next;
                    345:             } elsif ($line eq 'There are others available too.') {
                    346:                 next;
                    347:             } else {
                    348:                 push(@clean_output,$line);
                    349:             }
                    350:         }
                    351:         if (@clean_output > 0) {
                    352:             open(TMPFILE,">>$tmpfile");
                    353:             my $message = join("\n",@clean_output);
                    354:             print TMPFILE $header.$message;
                    355:             close(TMPFILE);
                    356:             $append_to_subj= ' RPMS to upgrade';
                    357:             $sendflag = 1;
                    358:         }
                    359:     } else {
                    360:         $append_to_subj = ' Error running RPM update check';
                    361:         $sendflag = 1;
                    362:     }
                    363:     return ($sendflag,$append_to_subj);
                    364: }
                    365: 
1.11    ! raeburn   366: sub check_with_apt {
        !           367:     my ($tmpfile) = @_;
        !           368:     my $apt = '/usr/bin/apt-get';
        !           369:     my $sendflag = 0;
        !           370:     my $append_to_subj;
        !           371:     my $header;
        !           372:     my @chg_package;
        !           373:     #
        !           374:     # Execute apt-get command to update distributions
        !           375:     system ("$apt update > /dev/null");
        !           376:     my $returnvalue = $?>>8;
        !           377:     if ($returnvalue == 0) {
        !           378:         # Execute apt-get commands to check for upgrades
        !           379:         if (open (PIPE, "$apt -y --dry-run upgrade  2>&1 |")) {
        !           380:             my @output=<PIPE>;
        !           381:             close(PIPE);
        !           382:             chomp(@output);
        !           383:             foreach my $line (@output) {
        !           384:                 $line =~ s/^\s+//;
        !           385:                 my @items = split(/\s+/,$line);
        !           386:                 if ($items[0] eq "Inst") {
        !           387:                     push(@chg_package,$items[1]);
        !           388:                 }
        !           389:             }
        !           390:             if (@chg_package > 0) {
        !           391:                 $header = 'apt-get upgrade found the following packages need updating:'.
        !           392:                           "\n\n";
        !           393:                 open(TMPFILE,">>$tmpfile");
        !           394:                 my $message = join("\n",@output);
        !           395:                 print TMPFILE $header.$message;
        !           396:                 close(TMPFILE);
        !           397:                 $append_to_subj= ' deb packages to upgrade';
        !           398:                 $sendflag = 1;
        !           399:             }
        !           400:         } else {
        !           401:             $append_to_subj = ' Error running deb upgrade check';
        !           402:             $sendflag = 1;
        !           403:         }
        !           404:     } else {
        !           405:         $append_to_subj = ' Error running deb update check';
        !           406:         $sendflag = 1;
        !           407:     }
        !           408:     return ($sendflag,$append_to_subj);
        !           409: }
        !           410: 
1.1       raeburn   411: sub check_with_checkrpms {
                    412:     my ($tmpfile,$perlvar) = @_;
                    413:     my $checkrpms = '/usr/local/bin/check-rpms';
                    414:     my $sendflag = 0;
                    415:     my $append_to_subj;
                    416: 
                    417:     # Run Martin Seigert's checkrpms script.  See
                    418:     # See http://www.sfu.ca/acs/security/linux/check-rpms.html 
                    419:     # for more information.
                    420: 
                    421:     #
                    422:     # Check that checkrpms is installed and is the proper version...
                    423:     if (! -e $checkrpms) {
                    424:        open(TMPFILE,">>$tmpfile");
                    425:        print TMPFILE <<END;
                    426: 
                    427: Unable to locate check-rpms on your system.  Please go to
                    428: http://www.sfu.ca/acs/security/linux/check-rpms.html, download and
                    429: install check-rpms on this system.
                    430: 
                    431: END
                    432:         $append_to_subj = ' Error running RPM update check';
                    433:         $sendflag = 1; 
                    434:     } else {
                    435:         #
                    436:         # Run check-rpms and capture its output
                    437:         if (open (PIPE, "$checkrpms 2>&1 |")) {
                    438:             my $output=<PIPE>;
                    439:             close(PIPE);
                    440:             if ($output ne '') {
                    441:                 $output = <<"END";
                    442: 
                    443: checkrpms checked the status of the packages on your system and
                    444: produced the following output:
                    445: -------------------------------------------------------
                    446: $output
                    447: -------------------------------------------------------
                    448: If there are rpms which need to be installed, please log into
                    449: $perlvar->{'lonHostID'} and run the following command
                    450: 
                    451: $checkrpms --update
                    452: 
                    453: If there are kernel packages to be installed, use
                    454: 
                    455: $checkrpms --update --install-kernel
                    456: 
                    457: Keeping your system up to date is very important.
                    458: Ensuring you are using up to date software is a prerequisite for a
                    459: secure system.
                    460: 
                    461: END
                    462:                 open(TMPFILE,">>$tmpfile");
                    463:                 print TMPFILE $output;
                    464:                 close(TMPFILE);
                    465:                 $append_to_subj = ' RPMS to upgrade';
                    466:                 $sendflag = 1; 
                    467:             }
                    468:         }
                    469:     }
                    470:     return ($sendflag,$append_to_subj);
                    471: }

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