#!/bin/bash # tmverifyrpms.sh # Check a set of rpms against a reference. # Ideas from David Cox's perl script ported to bash # creates tmverifyrpms.log in repository where it is run in the form of: # rpmname-cmp OK|OK-PERFECT|FAIL ref:refsize +/-:sizediffabs %:sizediff% # Where # - refsize is the rpm -q --qf %{SIZE} of the ref rpm # - sizediff% is the % difference between cmp and ref # - sizediffabs is the difference in bytes # If there are library, or file name/perm differences, create # reports/rpm.out # # Version 4.1.5-CentOS # 2011-03-10 Johnny Hughes # - Modified to build several secondary files to tell you about # RPMS in the compare or reference directories that do not # match up with each other. # - Modified to ignore different dist tags # - Modified to put a WARNING in the logs if the release does not # match between two files. # 2007-02-27 Johnny Hughes # - Modified so that it will match some of the standard file # extensions we use (.centos, .c4. .el4.centos) with their # reference counterparts w/o those extensions # 2005-07-13 Johnny Hughes # - Modified David's great script to run standalone # for using in CentOS compares. # - Removed many of the features (run in background, # srpms maps, etc.) which are not needed in this # implementation of the script # # You can get all of David's tmtools as a group # from the /tmtools directory of any taolinux # mirror. See http://www.taolinux.com for details # # Thanks to David for a great script :) # # Version 4.1.4 # 2004-12-23 David L. Parsley # - Sort rpm --requires output # 2004-12-21 parsley@linuxjedi.org # - Findrepo & cd there first (to run in subdirs) # - Put error checking before the fork-to-background # 2004-12-03 parsley@linuxjedi.org # - Discard rpm errors # - Fix sign error in SZDIFF # 2004-11-30 parsley@linuxjedi.org # - Strip (xxx) from end (ld-linux.so mainly) # - Add checking of rpm --requires # 2004-09-30 David L. Parsley # - use mktemp -u, or files will be mode 600 # 2004-05-16 David L. Parsley # - Add user & group to fingerprinting # - Strip right-hand-side of library linkages (after =>) # - dump stderr by default (can override locally) # 2004-05-01 David L. Parsley j # - use rpm --dump for files, can run unpriv #set -x # # This has been modified to become a standalone compare tool # by Johnny Hughes for CentOS compares on 7/13/2005 # #This is where the reference files are REFDIR=RHEL #This is the files to be compared CMPDIR=CentOS STARTDIR=`pwd` RPTDIR=reports WORKDIR=work > tmverifyrpms.log if [ -e $WORKDIR ] then rm -rf $WORKDIR fi mkdir -p $RPTDIR $WORKDIR rpmarch(){ STRIPPED=${1%.rpm} echo ${STRIPPED##*.} } genfilelist(){ rpm -qp --dump $1 2>/dev/null | LC_ALL=C sort | while read DUMPLINE do DUMPLINE=${DUMPLINE/ [01] [01] /TMLINESEP} FSYMLINK=${DUMPLINE#*TMLINESEP* } DUMPLINE=${DUMPLINE%TMLINESEP*} FILENAME="${DUMPLINE% * * * * * *}" REST=${DUMPLINE#$FILENAME } set $REST echo "$FILENAME mode:$4 owner:$5 group:$6 linkto:$FSYMLINK" done } comprpms(){ PKGOK="OK" CMPRPMDIR=`mktemp -d /var/tmp/cmprpm.XXXXXX` REFRPMDIR=`mktemp -d /var/tmp/refrpm.XXXXXX` rm -f $RPTDIR/$1.out cd $STARTDIR rpm2cpio $CMPDIR/$1 | ( cd $CMPRPMDIR; cpio -id --no-absolute-filenames --quiet ) rpm2cpio $REFDIR/$2 | ( cd $REFRPMDIR; cpio -id --no-absolute-filenames --quiet ) cd $CMPRPMDIR find . ! -type d | while read FILENAME do if [ -x "$FILENAME" -a -f "$FILENAME" ] then echo $FILENAME >> $STARTDIR/$WORKDIR/$CMPDIR-libs ldd $FILENAME | sort >> $STARTDIR/$WORKDIR/$CMPDIR-libs fi done cd $REFRPMDIR find . ! -type d | while read FILENAME do if [ -x "$FILENAME" -a -f "$FILENAME" ] then echo $FILENAME >> $STARTDIR/$WORKDIR/$REFDIR-libs ldd $FILENAME | sort >> $STARTDIR/$WORKDIR/$REFDIR-libs fi done cd $STARTDIR genfilelist $CMPDIR/$1 > $STARTDIR/$WORKDIR/$CMPDIR-list genfilelist $REFDIR/$2 > $STARTDIR/$WORKDIR/$REFDIR-list diff -u $WORKDIR/*list > $WORKDIR/rpmdiff if [ $? -eq 1 ] then PKGOK="FAIL" echo "Differing file fingerprints:">> $RPTDIR/$1.out cat $WORKDIR/rpmdiff >> $RPTDIR/$1.out fi rpm -qp --requires $CMPDIR/$1 2>/dev/null | LC_ALL=C sort >$STARTDIR/$WORKDIR/$CMPDIR-req rpm -qp --requires $REFDIR/$2 2>/dev/null | LC_ALL=C sort >$STARTDIR/$WORKDIR/$REFDIR-req diff -u $WORKDIR/*req > $WORKDIR/reqdiff if [ $? -eq 1 ] then PKGOK="FAIL" echo "Differing package requirements:">> $RPTDIR/$1.out cat $WORKDIR/reqdiff >> $RPTDIR/$1.out fi if [ -e $WORKDIR/$REFDIR-libs ] then # Only want what it's looking for, not what it actually gets perl -pi -e 's/ =>.*//' $WORKDIR/$CMPDIR-libs perl -pi -e 's/ =>.*//' $WORKDIR/$REFDIR-libs perl -pi -e 's/ \(.*//' $WORKDIR/$CMPDIR-libs perl -pi -e 's/ \(.*//' $WORKDIR/$REFDIR-libs diff -u $WORKDIR/*libs > $WORKDIR/libdiff if [ $? -eq 1 ] then PKGOK="FAIL" echo "Differing libraries:">> $RPTDIR/$1.out cat $WORKDIR/libdiff >> $RPTDIR/$1.out echo "ldd for $CMPDIR-rpm:">> $RPTDIR/$1.out cat $WORKDIR/$CMPDIR-libs >> $RPTDIR/$1.out echo "ldd for $REFDIR-rpm:">> $RPTDIR/$1.out cat $WORKDIR/$REFDIR-libs >> $RPTDIR/$1.out fi fi if [ -e $WORKDIR/$CMPDIR-libs ] then grep -q 'not found' $WORKDIR/$CMPDIR-libs if [ $? -eq 0 ] then PKGOK="FAIL" echo "Missing libraries:" \ >> $RPTDIR/$1.out cat $WORKDIR/$CMPDIR-libs >> $RPTDIR/$1.out fi fi cd $WORKDIR rm -f libdiff rpmdiff $CMPDIR-libs $REFDIR-libs cd $STARTDIR # MORE TESTS HERE CMPSIZE=`rpm -qp --qf %{SIZE} $CMPDIR/$1 2>/dev/null` REFSIZE=`rpm -qp --qf %{SIZE} $REFDIR/$2 2>/dev/null` SZDIFF=$(($CMPSIZE - $REFSIZE)) ABSDIFF=$((SZDIFF<0?-$SZDIFF:$SZDIFF)) if [ $REFSIZE -ne 0 ] then PCTDIFF=$(($ABSDIFF * 100 / $REFSIZE)) else PCTDIFF=-0- fi if [ $PKGOK = "OK" -a $SZDIFF -eq 0 ] then PKGOK="OK-PERFECT" fi rm -rf $CMPRPMDIR $REFRPMDIR RESULTS="$1 $PKGOK ref:$REFSIZE +/-:$SZDIFF %:$PCTDIFF" } # start the required files over if [ -e "$REFDIR"_rpm.lst ]; then rm -f "$REFDIR"_rpm.lst fi if [ -e "$CMPDIR"_rpm.lst ]; then rm -f "$CMPDIR"_rpm.lst fi if [ -e extra_files_"$REFDIR".lst ]; then rm -f extra_files_"$REFDIR".lst fi if [ -e extra_files_"$CMPDIR".lst ]; then rm -f extra_files_"$CMPDIR".lst fi cd $REFDIR for REFRPM in `echo *.rpm` do REFRPM_NVR=`rpm -qp --qf '%{name}-%{version}.%{arch}\n' $REFRPM` echo $REFRPM_NVR" "$REFRPM >> ../"$REFDIR"_rpm.lst done cd $STARTDIR # Get list of rpms to compare cd $CMPDIR RPMLIST=`echo *.rpm` cd $STARTDIR for CMPRPM in $RPMLIST do CMPRPM_NVR=`rpm -qp --qf '%{name}-%{version}.%{arch}' $CMPDIR/$CMPRPM` echo $CMPRPM_NVR" "$CMPRPM >> "$CMPDIR"_rpm.lst REFRPM_ONLIST=`grep "^$CMPRPM_NVR " "$REFDIR"_rpm.lst` if [ "$REFRPM_ONLIST"x != x ]; then REFRPM2=`echo $REFRPM_ONLIST | awk {'print $2'}` echo -n "Verifying $CMPRPM against $REFRPM2" comprpms $CMPRPM $REFRPM2 echo "" echo $RESULTS if [ "$CMPRPM" != "$REFRPM2" ]; then echo "WARNING: $CMPRPM and $REFRPM2 are not an exact name match" fi echo "-------------------------" else echo $CMPRPM" was not checked" >> extra_files_"$CMPDIR".lst fi done >> tmverifyrpms.log for REFRPM in `cat "$REFDIR"_rpm.lst | awk {'print $2'}` do REFRPM_NVR=`grep "$REFRPM" "$REFDIR"_rpm.lst | awk {'print $1'}` CMPRPM_ONLIST=`grep "^$REFRPM_NVR " "$CMPDIR"_rpm.lst` if [ "$CMPRPM_ONLIST"x == x ]; then echo $REFRPM" is missing from the "$CMPDIR directory >> extra_files_"$REFDIR".lst fi done echo "Finished." >> tmverifyrpms.log