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