Annotation of loncom/build/CHECKRPMS, revision 1.17

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.