• Home

  • Custom Ecommerce
  • Application Development
  • Database Consulting
  • Cloud Hosting
  • Systems Integration
  • Legacy Business Systems
  • Security & Compliance
  • GIS

  • Expertise

  • About Us
  • Our Team
  • Clients
  • Blog
  • Careers

  • CasePointer

  • VisionPort

  • Contact
  • Our Blog

    Ongoing observations by End Point Dev people

    Comparing installed RPMs on two servers

    Jon Jensen

    By Jon Jensen
    September 27, 2013

    Sometimes I’m called on to deal with a problem that shows up only on one of two or more servers that are supposed to be configured identically, or nearly identically. One of the first things I do is run rpm -qa | sort on each machine and diff the output to see which RPM packages may be missing on one or the other server. I’ve never bothered to package this functionality up into a script because it’s so simple.

    To exclude minor version differences, you need to specify a custom rpm --queryformat that leaves the version number off.

    To understand what you’re seeing when it appears that some package is different but seems the same, you’re often looking at multiple architectures of packages (e.g. i386 and x86_64) which RPM doesn’t show in its default query format.

    Finally, to turn the diff output into a list of RPMs to install via yum, I usually do some combination of grep and sed to pick out the RPMs I need.

    After all that the process isn’t entirely simple anymore, and I recently decided it was easier to script it than explain it all to someone else. I first looked around to see what scripts others have come up with, since this is certainly not a new need. I found the blog post “Compare the RPM Packages Installed on Two Different Servers” which gives a very simple example of the manual labor version I’ve long done.

    In that blog post’s comments, people link to various scripts others have done. I checked them out and found that they are all way overcomplicated for my needs, and the simple approach I want just needed to be scripted after all. So here is my script:

    #!/bin/sh
    
    test -n "$TMPDIR" || TMPDIR=/tmp
    tmpfilebase="$TMPDIR/rpmdb-compare.$$"
    
    if test $# -ne 2
    then
        echo "Usage: $0 [user@]server1 [user@]server2" >&2
        echo "Special name localhost means this server, without ssh" >&2
        exit 1
    fi
    
    for i in "$@"
    do
        tmpfile="$tmpfilebase.$i"
        if test $i = localhost
        then
            rpm -qa --qf '%{NAME}.%{ARCH}\n' | sort > $tmpfile
        else
            ssh $i "rpm -qa --qf '%{NAME}.%{ARCH}\n'" | sort > $tmpfile
        fi
    done
    
    echo "RPMs in $1 only:"
    comm -23 "$tmpfilebase.$1" "$tmpfilebase.$2"
    
    echo
    echo "RPMs in $2 only:"
    comm -13 "$tmpfilebase.$1" "$tmpfilebase.$2"
    
    rm -f "$tmpfilebase.$1" "$tmpfilebase.$2"
    

    I noticed one of those commenters mentioned using comm instead of diff/grep/sed, and so I used that too. Now the script is easier for me too, and helps avoid copying and leaving temporary files sitting around.

    To run it, just do:

    ./rpmdb-compare host1 host2 > mylist
    

    With the output redirected to file mylist, you can edit it to result in a list of RPMs that need to be installed on one server, then do this on that server:

    < mylist yum -y install
    

    It’s a good idea to test it first without the -y option, which will cause yum to abort the installation and gives you a chance to see if any unexpected dependencies will be dragged in.

    Also, don’t blindly install every package you don’t know the purpose of. Watch out for RPMs that may not belong everywhere due to hardware differences such as Ethernet firmware, RAID controller, IPMI, etc.

    hosting redhat sysadmin


    Comments