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