--- loncom/build/CHECKRPMS 2006/10/04 19:47:33 1.3 +++ loncom/build/CHECKRPMS 2024/10/24 16:38:32 1.20 @@ -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.20 2024/10/24 16:38:32 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/Oracle Linux/SuSE/SLES) + or debs (Debian/Ubuntu) on a system. =head1 DESCRIPTION @@ -39,10 +42,14 @@ to LON-CAPA systems. distprobe is used t The utility which is used to complete the check depends on the distro: -fedora - yum +fedora < 22; rhel (5, 6, 7); centos/scientific/oracle linux <=7 - yum +fedora >= 22 - dnf +rhel/centos/oracle/rocky/alma linux >= 8 - dnf suse 9.X and sles9 - you -suse 10.X and sles10 - rug +suse 10.2, 10.3, 11.X and 12.X; sles (>= 11) - 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 +61,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 +87,92 @@ 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_yum_or_dnf($tmpfile,'dnf'); + } else { + $cmd = 'yum update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum_or_dnf($tmpfile,'yum'); + } +} 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 <= 7) { + $cmd = 'yum update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum_or_dnf($tmpfile,'yum'); + } else { + $cmd = 'dnf update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum_or_dnf($tmpfile,'dnf'); + } +} elsif ($distro =~ /^(?:centos|scientific|oracle|rocky|alma)(\d+)$/) { + my $version = $1; + if ($version <= 7) { + $cmd = 'yum update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum_or_dnf($tmpfile,'yum'); + } else { + $cmd = 'dnf update'; + &prepare_msg($tmpfile,$cmd); + ($send,$addsubj) = &check_with_yum_or_dnf($tmpfile,'dnf'); + } +} elsif ($distro =~ /^(debian|ubuntu)\d+/) { + $cmd = 'apt-get upgrade'; &prepare_msg($tmpfile,$cmd); - ($send,$addsubj) = &check_with_up2date($tmpfile); + ($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 +187,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 +200,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; @@ -143,21 +234,26 @@ sub check_with_you { return ($sendflag,$append_to_subj); } -sub check_with_yum { - my ($tmpfile) = @_; - my $yum = '/usr/bin/yum'; +sub check_with_yum_or_dnf { + my ($tmpfile,$progname) = @_; + my $path_to_exec = '/usr/bin/'; + if ($progname eq 'dnf') { + $path_to_exec .= $progname; + } else { + $path_to_exec .= 'yum'; + } my $sendflag = 0; my $append_to_subj; # - # Execute yum command - my $command = $yum.' check-update '.'>>'.$tmpfile; + # Execute command + my $command = $path_to_exec.' check-update '.'>>'.$tmpfile; system($command); my $returnvalue = $?>>8; # - # Determine status of yum run + # Determine status of yum or dnf run if (100 == $returnvalue) { $sendflag = 1; $append_to_subj = ' RPMS to upgrade'; @@ -165,7 +261,7 @@ sub check_with_yum { $sendflag = 1; $append_to_subj = ' Error running RPM update script'; } else { - # yum returned 0, so everything is up to date. + # yum or dnf returned 0, so everything is up to date. } return ($sendflag,$append_to_subj); } @@ -181,13 +277,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); @@ -232,6 +335,8 @@ sub check_with_rug { last; } elsif ($line eq 'No updates are available.') { last; + } elsif ($line eq 'Downloading Packages...') { + last; } else { push(@clean_output,$line); } @@ -248,6 +353,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 {