--- loncom/build/CHECKRPMS 2006/10/03 00:34:59 1.1 +++ loncom/build/CHECKRPMS 2017/04/09 14:54:02 1.17 @@ -1,8 +1,10 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # # The LearningOnline Network with CAPA # Checks status of RPM packages on system. # +# $Id: CHECKRPMS,v 1.17 2017/04/09 14:54:02 raeburn Exp $ +# # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). @@ -30,7 +32,8 @@ =head1 NAME -B - automated status report about RPMs on a system. +B - automated status report about RPMs (RHEL/Fedora/CentOS/SuSE) + or debs (Debian/Ubuntu) on a system. =head1 DESCRIPTION @@ -39,10 +42,13 @@ to LON-CAPA systems. distprobe is used t The utility which is used to complete the check depends on the distro: -fedora - yum +fedora, rhel >= 5, centos, scientific - yum +fedora >= 22 - dnf suse 9.X and sles9 - you -suse 10.X and sles10 - rug +suse 10.2,10.3,11.1,11.2,11.3,11.4,sles11 - zypper +sles10,suse10.1 - rug rhel 4 - up2date +debian, ubuntu - apt-get others - check-rpms Created by amalgamating previous distribution-specific CHECKRPMS.dist files (where dist was one of: fedora, rhel, suse, sles10, default). @@ -54,12 +60,17 @@ Must be run as root or www. use strict; use lib '/home/httpd/lib/perl/'; use LONCAPA::Configuration; +use Apache::loncommon(); my $tmpfile = '/tmp/CHECKRPMS.'.$$; my $perlvar= LONCAPA::Configuration::read_conf('loncapa.conf'); +my $docroot = $perlvar->{'lonDocRoot'}; # Determine who we email -my $emailto = "$perlvar->{'lonAdmEMail'}"; +my $defdom = $perlvar->{'lonDefDomain'}; +my $origmail = $perlvar->{'lonAdmEMail'}; +my $emailto = &Apache::loncommon::build_recipient_list(undef, + 'packagesmail',$defdom,$origmail); my $subj = $perlvar->{'lonHostID'}; # Get Linux distro @@ -75,30 +86,85 @@ open(TMPFILE,">$tmpfile"); print TMPFILE localtime(time).' '.$hostname."\n"; close(TMPFILE); +if ($docroot ne '') { + if (-e "$docroot/lon-status/checkrpms.txt") { + unlink("$docroot/lon-status/checkrpms.txt"); + } +} + my ($cmd,$send,$addsubj); -if ($distro =~ /^fedora\d+$/) { - $cmd = 'yum update'; - &prepare_msg($tmpfile,$cmd); - ($send,$addsubj) = &check_with_yum($tmpfile); -} elsif ($distro =~ /^(suse|sles)9\.\d$/) { +if ($distro =~ /^fedora(\d+)$/) { + my $version =$1; + if ($version > 21) { + $cmd = 'dnf update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_dnf($tmpfile); + } else { + $cmd = 'yum update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum($tmpfile); + } +} elsif ($distro =~ /^(suse|sles)9\.?\d?$/) { $cmd = 'you'; &prepare_msg($tmpfile,$cmd); ($send,$addsubj) = &check_with_you($tmpfile); -} elsif ($distro =~ /^(suse|sles)10\.?\d?$/) { +} elsif ($distro =~ /^suse(\d{2,})\.(\d+)$/) { + my $version =$1; + my $subversion = $2; + if (($version > 10) || (($version == 10) && ($subversion > 1))) { + $cmd = 'zypper up'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_zypper($tmpfile); + } else { + $cmd = 'rug up'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_rug($tmpfile); + } +} elsif ($distro =~ /^sles10$/) { $cmd = 'rug up'; &prepare_msg($tmpfile,$cmd); ($send,$addsubj) = &check_with_rug($tmpfile); -} elsif ($distro =~ /^rhes4$/) { - $cmd ='up2date -u --nox'; +} elsif ($distro =~ /^sles(\d+)$/) { + $cmd = 'zypper up'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_zypper($tmpfile); +} elsif ($distro =~ /^rhes(\d+)$/) { + my $version = $1; + if ($version == 4) { + $cmd ='up2date -u --nox'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_up2date($tmpfile); + } elsif ($version > 4) { + $cmd = 'yum update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum($tmpfile); + } +} elsif ($distro =~ /^centos\d+$/) { + $cmd = 'yum update'; &prepare_msg($tmpfile,$cmd); - ($send,$addsubj) = &check_with_up2date($tmpfile); + ($send,$addsubj) = &check_with_yum($tmpfile); +} elsif ($distro =~ /^scientific\d+$/) { + $cmd = 'yum update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum($tmpfile); +} elsif ($distro =~ /^(debian|ubuntu)\d+/) { + $cmd = 'apt-get upgrade'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_apt($tmpfile); } else { $cmd = '/usr/local/bin/check-rpms --update'; ($send,$addsubj) = &check_with_checkrpms($tmpfile); } if ($send) { $subj .= $addsubj; - system(qq{mail -s '$subj' $emailto < $tmpfile}); + if ($docroot ne '') { + system("cat $tmpfile > $docroot/lon-status/checkrpms.txt"); + if ($< == 0) { + system("chown www:www $docroot/lon-status/checkrpms.txt"); + } + chmod(0600,"$docroot/lon-status/checkrpms.txt"); + } + system(qq{mail -s '$subj' "$emailto" < $tmpfile}); } sub prepare_msg { @@ -113,7 +179,7 @@ $cmd to bring it up to date. -This is very important for the security of your server. The table below lists the packages which need to be updated. +This is very important for the security of your server. The packages which need to be updated are listed below. ENDHEADER close(TMPFILE); @@ -126,15 +192,32 @@ sub check_with_you { my $sendflag = 0; my $append_to_subj; - if (open (PIPE, "$you -d -k -l en 2>&1 |")) { + if (open (PIPE, "$you -k -len 2>&1 |")) { my $output=; close(PIPE); chomp $output; unless ($output eq 'No updates available.') { - my $command = $you.' -s -k -l en |grep ^[^I] >>'.$tmpfile; - system($command); - $sendflag = 1; - $append_to_subj = ' RPMS to upgrade'; + if (open (PIPE, "$you -s -d -len |grep ^INSTALL |")) { + my @updates = ; + close(PIPE); + my $allpackages; + foreach my $line (@updates) { + my $package = substr($line,rindex($line,'/')+1); + if ($package ne '') { + $allpackages .= $package; + } + } + if ($allpackages ne '') { + open(TMPFILE,">>$tmpfile"); + print TMPFILE $allpackages; + close(TMPFILE); + $sendflag = 1; + $append_to_subj = ' RPMS to upgrade'; + } + } else { + $sendflag = 1; + $append_to_subj = ' Error running RPM update script'; + } } } else { $sendflag = 1; @@ -170,6 +253,33 @@ sub check_with_yum { return ($sendflag,$append_to_subj); } +sub check_with_dnf { + my ($tmpfile) = @_; + my $dnf = '/usr/bin/dnf'; + my $sendflag = 0; + my $append_to_subj; + + # + # Execute dnf command + my $command = $dnf.' check-update '.'>>'.$tmpfile; + system($command); + + my $returnvalue = $?>>8; + + # + # Determine status of dnf run + if (100 == $returnvalue) { + $sendflag = 1; + $append_to_subj = ' RPMS to upgrade'; + } elsif (0 != $returnvalue) { + $sendflag = 1; + $append_to_subj = ' Error running RPM update script'; + } else { + # dnf returned 0, so everything is up to date. + } + return ($sendflag,$append_to_subj); +} + sub check_with_up2date { my ($tmpfile) = @_; my $up2date = '/usr/bin/up2date-nox'; @@ -181,13 +291,20 @@ sub check_with_up2date { if (open (PIPE, "$up2date -l 2>&1 |")) { my @result=; close(PIPE); + my $output; + foreach my $line (@result) { + if ($line =~ /^The following Packages were marked to be skipped by your configuration:/) { + last; + } else { + $output .= $line; + } + } if (@result > 0) { - my $output = join('',@result); if ($output =~ /Fetching Obsoletes list/) { $up2date_error = 0; if ($output =~ /Name\s+Version\s+Rel\s+[\n\r\f]+\-+[\n\r\f]+(.+)/s) { my $packagelist = $1; - unless (($packagelist =~ /^The following Packages were marked to be skipped by your configuration:/) || ($packagelist eq '')) { + if ($packagelist ne '' && $packagelist !~ /^[\s\n\r\f]+$/) { open(TMPFILE,">>$tmpfile"); print TMPFILE $packagelist; close(TMPFILE); @@ -218,10 +335,21 @@ sub check_with_rug { chomp(@output); my @clean_output; foreach my $line (@output) { - if ($line eq 'Waking up ZMD...' || $line eq 'Done') { + if ($line =~ /^Waking\sup\sZMD\.\.\./) { next; - } - if ($line eq 'No updates are available.') { + } elsif ($line eq 'Done') { + next; + } elsif ($line eq '') { + next; + } elsif ($line eq 'The following packages will be installed:') { + next; + } elsif ($line eq 'Resolving Dependencies...') { + next; + } elsif ($line eq 'Transaction...') { + last; + } elsif ($line eq 'No updates are available.') { + last; + } elsif ($line eq 'Downloading Packages...') { last; } else { push(@clean_output,$line); @@ -239,6 +367,100 @@ sub check_with_rug { $sendflag = 1; } return ($sendflag,$append_to_subj); +} + +sub check_with_zypper { + my ($tmpfile) = @_; + my $zypper = '/usr/bin/zypper'; + my $sendflag = 0; + my $append_to_subj; + my $header; + # + # Execute zypper command to check for updates + if (open (PIPE, "$zypper lu 2>&1 |")) { + my @output=; + close(PIPE); + chomp(@output); + my @clean_output; + foreach my $line (@output) { + if ($line eq 'Restoring system sources...') { + next; + } elsif ($line =~ /^Parsing\smetadata\sfor\s/) { + next; + } elsif ($line eq 'Parsing RPM database...') { + next; + } elsif ($line =~ /^Catalog\s+\|\s+Name\s+\|\s+Version\s+\|\s+Category\s+\|\s+Status$/) { + $header = $line."\n"; + next; + } elsif ($line =~ /^[-+]+$/) { + $header .= $line."\n"; + next; + } elsif ($line eq 'WARNING: These are only the updates affecting the updater itself.') { + next; + } elsif ($line eq 'There are others available too.') { + next; + } else { + push(@clean_output,$line); + } + } + if (@clean_output > 0) { + open(TMPFILE,">>$tmpfile"); + my $message = join("\n",@clean_output); + print TMPFILE $header.$message; + close(TMPFILE); + $append_to_subj= ' RPMS to upgrade'; + $sendflag = 1; + } + } else { + $append_to_subj = ' Error running RPM update check'; + $sendflag = 1; + } + return ($sendflag,$append_to_subj); +} + +sub check_with_apt { + my ($tmpfile) = @_; + my $apt = '/usr/bin/apt-get'; + my $sendflag = 0; + my $append_to_subj; + my $header; + my @chg_package; + # + # Execute apt-get command to update distributions + system ("$apt update > /dev/null"); + my $returnvalue = $?>>8; + if ($returnvalue == 0) { + # Execute apt-get commands to check for upgrades + if (open (PIPE, "$apt -y --dry-run upgrade 2>&1 |")) { + my @output=; + close(PIPE); + chomp(@output); + foreach my $line (@output) { + $line =~ s/^\s+//; + my @items = split(/\s+/,$line); + if ($items[0] eq "Inst") { + push(@chg_package,$items[1]); + } + } + if (@chg_package > 0) { + $header = 'apt-get upgrade found the following packages need updating:'. + "\n\n"; + open(TMPFILE,">>$tmpfile"); + my $message = join("\n",@output); + print TMPFILE $header.$message; + close(TMPFILE); + $append_to_subj= ' deb packages to upgrade'; + $sendflag = 1; + } + } else { + $append_to_subj = ' Error running deb upgrade check'; + $sendflag = 1; + } + } else { + $append_to_subj = ' Error running deb update check'; + $sendflag = 1; + } + return ($sendflag,$append_to_subj); } sub check_with_checkrpms {