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