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