How do *you* retrieve the release version on your systems?

Latest response

I am looking for a clean/easy/simple way to gather the release version (specific only to the 5/6/7 EL releases, I suppose).
I have considered using the following files/commands:
/etc/redhat-release
/etc/system-release-cpe
lsb-release
uname -r

The problem I am running in to with any of the above methods is the lack of consistency (either due to differing build standards on my hosts, or the output is slightly different).
For example:
/etc/redhat-release (seems consistent thus far regarding the number of fields - however, Fedora is different and I have not tested CentOS)
/etc/system-release-cpe (was not implemented on RHEL 5 - AFAIK)
lsb-release (not all of my systems have lsb installed)
uname -r (parsing for el5 vs el6, etc... might be the ticket?)

I'm just wondering what other folks are doing. My bootstrap script determines which activation key to use based on the OS release and a few of my 3rd-party Repositories as well. I'm searching for the lowest common denominator(s) or most consistent way to determine the information.

Then there is things like this (notice column 5)

#  cat /etc/system-release-cpe
cpe:/o:redhat:enterprise_linux:6server:ga:server
# cat /etc/system-release-cpe
cpe:/o:redhat:enterprise_linux:7.0:ga:server

Then... notice the difference in the yum vars (6server vs 6Server)

# python -c 'import yum, pprint; yb = yum.YumBase(); pprint.pprint(yb.conf.yumvar, width=1)'
{'arch': 'amd64',
 'basearch': 'x86_64',
 'releasever': '6Server',

EDIT: I apologize - I should have mentioned that I am doing this from the client itself. So, I need a consistent command that could be run on a RHEL 5/6/7 client (Sorry for the confusion)

Responses

James,

Although it may be cheating a little, I use facter that is installed due to Puppet, and it makes it an extremely simple affair:

facter operatingsystemmajrelease
6
facter  operatingsystemrelease
6.5

I haven't pulled these 'facts' apart (ie. how they are determined), but I have found them reliable in my environment. You can install just the facter package.. it comes in extremely handy for retrieving system details in scripts.

Red Hat packaged version here:
https://rhn.redhat.com/rhn/software/packages/details/Overview.do?pid=699964

The EPEL version is a little newer but not current (may be due to deps):
http://dl.fedoraproject.org/pub/epel/6/x86_64/repoview/facter.html

Source RPMs are available from PuppetLabs:
https://yum.puppetlabs.com/el/6/products/SRPMS/

Hi James,

Also see next comment, this link and Dag Wieers' input

I've found some database and other admin teams occasionally will change the /etc/redhat-release file to something invalid ("invalid" here being the non-true release version of the system) just to get something like oracle or other third party software installed. There are some third party software packages that check for some version and fail unless someone manually changes the /etc/redhat-release file, which if course is not a good practice, but people do it when push comes to shove.

A team came to me with a server I did not know about, that was built by another contract or something. They claimed it was RHEL 4.x, however when I examined the system, it was not RHEL 4, but RHEL 5.2 and it had it's text file /etc/redhat-release version manually changed by someone because of the reason in the above paragraph (but not oracle in this case). I simply had to upgrade it to RHEL 5.11 after ingesting the previously unknown server to my satellite server.

So I'd recommend either the puppet method if that is feasable to you that Pixel mentions
-or- query the redhat-release rpm (server or workstation).

[root@yoursystem]# rpm -q redhat-release-server

I don't have a workstation as I type this... but I suspect this would work for workstation:

[root@yoursystem]# rpm -qa | grep redhat-release

I know you have a satellite server, I can give you a script (I use) for spacecmd or perhaps an API at a later time that would hit your systems with this query from a satellite server.

James, looks like I already posted this previously. Also, see Dag Wieers input in that discussion.

I periodically/persistently get request of what rpm and version is loaded on a specific system (among other requests).

Anyway, this is from the other thread for reference here. When I get the perl script template finished, I'll post it here (I get all rpms, nearly done with "next if" in the perl directives to narrow ths scope).

Sometimes our management or security folks are interested in a list of servers with the specific version with the minor point release. A command to produce this helps to generate the report they request periodically.
DISCLAIMER: Yes, the mere output of /etc/redhat-release should never be used to infer security compliance, that is a stark given for many obvious reasons!
However - this is useful to determine what sort of rpm (not just redhat-release) is installed and what version.

Here's a small rough query (I'm confident there's better ways) using spacecmd from EPEL. Shows the systems and their versions:


#!/bin/bash fqdn=acme.com /usr/bin/spacecmd package_listinstalledsystems redhat-release | egrep -v '^\#|^\-' | uniq

I experimented and pushed this script below as a scheduled query to my system group called "everything"

NOTE: SOME ADMINS CHANGE /etc/redhat-release just to load software, so querying the rpm redhat-release is probably better.

echo SEE WARNING ABOVE
[notroot@workstation1 ~]# cat /path/to/my/scripts/queryrhelver.sh
#!/bin/bash
echo -n `hostname -s` ": " `rpm -q redhat-release`
rpm -q 
echo

Then run the script to my system group named "everything"

First enter the spacecmd command UI
[notroot@workstation1 ~]# spacecmd -s SATSERVERNAME@FQDN
spacecmd {SSM:0}> system_runscript -f /path/to/my/scripts/queryrhelver.sh group:everything
User:       root
Group:      root
Timeout:    600 seconds
Start Time: 20140216T22:21:35

Script Contents
---------------
#!/bin/bash
echo -n `hostname -s` ": " `rpm -q redhat-release{workstation,server}`
# note the above line really works for RHEL server/workstation
echo


Systems
-------
four0four.myfqdn.com
three0one.myfqdn.com
---truncated output---

Is this ok [y/N]: y
INFO: Action ID: 1134
INFO: Scheduled: XXXX system(s)

Get the ID that the script ran from the use of spacecmd above (it is above too):

[notroot@workstation1 ~]# spacecmd schedule_listcompleted | grep arbitrary
INFO: Connected to https://myrhnserver/rpc/api as youknowwho
1134     20140216T16:51:18     XXXX    0    0    Run an arbitrary script
--truncated list---

Wait for the cron to pick up the 'rhn_check' command, then view completed scheduled script:

[notroot@workstation1 ~]# spacecmd schedule_listcompleted
INFO: Connected to https://myrhnserver/rpc/api as youknowwho
ID      Date                 C    F    P     Action
--      ----                ---  ---  ---    ------
1134     20140216T16:51:18     XXXX    0    0    Run an arbitrary script

Then view the output:
Important Note: Sadly, one can only run the egrep below from the actual Satellite server.


[notroot@myrhnserver ~]# fqdn=acme.com [notroot@myrhnserver ~]# spacecmd schedule_getoutput 1134 | egrep '$fqdn|release' INFO: Connected to https://myrhnserver/rpc/api as youknowwho four0four : Red Hat Enterprise Linux Server release 6.5 (Santiago) three0one : Red Hat Enterprise Linux Server release 6.5 (Santiago) ---truncated---

There's a chance the output in the last block may be actually different, I'll post later on this with an update

Thanks - I hadn't even noticed that Dag responded to my previous post ;-) I had to update my original post on this topic as I should have mentioned that I am looking for something client-side for this particular task.

To oversimply, I would do something like the following:

case $(some test here) in 
  7Server)
    var=${ORG_ID}-default-rhel7
  ;;
  6Server)
    var=${ORG_ID}-default-rhel6
  ;;
esac

James, my reply had assumed a purely Red Hat environment. My bit above goes after the RPM that owns /etc/redhat-release. However, if you use centos/scientific linux, and so forth, then of course - use the proper rpm query, or Dag's method or other recommended method from others that have posted.... That being said, has anyone found the rpm that Dag refers to? When I went to his link I only found Solaris binaries.

There's also the LSB method to detect distro, though ironically this package is not installed by default:

# rpm -q redhat-lsb-core
redhat-lsb-core-4.0-7.el6.x86_64

# lsb_release -a
LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description:    Red Hat Enterprise Linux Server release 6.6 (Santiago)
Release:        6.6
Codename:       Santiago
# rpm -q redhat-lsb-core
redhat-lsb-core-4.1-24.el7.x86_64

# lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: RedHatEnterpriseServer
Description:    Red Hat Enterprise Linux Server release 7.0 (Maipo)
Release:        7.0
Codename:       Maipo

The package is available under the same name on CentOS. It pulls in a lot of dependencies like gettext, glibc-devel, patch, mailx, perl so isn't particularly "minimal".

If you feel this is useful for you, please do raise an RFE to have redhat-lsb-core included in the base install of RHEL.

Agree with the dependency problem with LSB. The major problem I find with the LSB in general is that LSB defines printing support as a requirement, which drags in cups and several kitchen sinks along the way.

Thanks Pixel - I have run in to the same sort of issues regarding lsb packages - it is certainly nice to have around, but I don't know if I would feel comfortable doing a global push to all of my hosts that do not have the lsb packages currently based on all the additional "stuff".

Unfortunately, upon closer inspection, my facter suggestion may not solve your issue as under the covers it just uses the OS release files.
From the source:

# Resolution:
#   On RedHat derivatives, returns their '/etc/<variant>-release' file.
#   On Debian, returns '/etc/debian_version'.
#   On Ubuntu, parses '/etc/lsb-release' for the release version.
#   On Suse, derivatives, parses '/etc/SuSE-release' for a selection of version
#   information.
#   On Slackware, parses '/etc/slackware-version'.
#   On Amazon Linux, returns the 'lsbdistrelease' value.
#   On Mageia, parses '/etc/mageia-release' for the release version.
#
#   On all remaining systems, returns the 'kernelrelease' value.

Code that does the work:

Facter.add(:operatingsystemrelease) do
  confine :operatingsystem => %w{CentOS Fedora oel ovs OracleLinux RedHat MeeGo Scientific SLC Ascendos CloudLinux PSBM}
  setcode do
    case Facter.value(:operatingsystem)
    when "CentOS", "RedHat", "Scientific", "SLC", "Ascendos", "CloudLinux", "PSBM", "XenServer"
      releasefile = "/etc/redhat-release"
    when "Fedora"
      releasefile = "/etc/fedora-release"
    when "MeeGo"
      releasefile = "/etc/meego-release"
    when "OracleLinux"
      releasefile = "/etc/oracle-release"
    when "OEL", "oel"
      releasefile = "/etc/enterprise-release"
    when "OVS", "ovs"
      releasefile = "/etc/ovs-release"
    end

    if release = Facter::Util::FileRead.read(releasefile)
      line = release.split("\n").first.chomp
      if match = /\(Rawhide\)$/.match(line)
        "Rawhide"
      elsif match = /release (\d[\d.]*)/.match(line)
        match[1]
      end
    end
  end
end

"Best" will depend on how specific a version you're looking for. The various "/etc/-release" files are *supposed to be a good method for doing so across various Linux (and other) operating systems.

That said, if your environment isn't trustworthy, in that regard (people "massaging" its contents to facilitate application installs), you can still generally look at the RPM that owns the /etc/-release file for your OS. While people might alter the contents of the installed /etc/-release files, they don't generally go so far as to alter the RPM database for the RPM that owns the /etc/*-release files. Thus, you'll still be able to get your ELx version and your ELx.y version. Only real down-side is that your system query-script will need to know "on Red Hat systems, I do rpm -q redhat-release, on CentOS systems I do rpm -q centos-release, on..."

Thanks Tom - checking the redhat-release will likely be the route I go (and thanks for the push in that direction ;-)

However - and I don't know why this is the way it is:
redhat-release-server.x86_64 7.0-1.el7
redhat-release-server.x86_64 6Server-6.5.0.1.el6
redhat-release.x86_64 5Server-5.11.0.2

and a glob for /etc/*release unfortunately includes /etc/lsb-release ;-)

I guess I don't feel that bad any more that I thought I had missed the "silver bullet" to this issue ;-) I guess I'll need to brush up on my regex!

In general, the rpm --qf <FORMATSPEC> -q <vendor>-release will likely be the safest method. That is, don't used globs - just look for the specific <vendor>-release RPM.

That said, if you're like me, you probably hate hard-coding and would rather let the system sort itself out. I know that both CentOS and Scientific Linux retain the /etc/redhat-release file: Scientific Linux straight-up replaces the "RedHat" content with their own; CentOS has an /etc/centos-release file that /etc/redhat-release points to. Haven't played with Fedora, recently, to know what it has. At any rate, you could always do something like rpm -qf /etc/redhat-release to get the applicable RPM name, then use that programatically-derived RPM name to do your further version queries.

James,

Hopefully you don't have anyone "massaging" the /etc/{redhat,centos}-release file... I've only had that on a minority of systems. The method I had posted previously above (updated for server/workstation) will query against the rpm that owns /etc/redhat-release. Of course see the other good suggestions others provided.

You can use

subscription-manager facts --list | grep distribution

But, that is similar to facter in that it is reading the /etc files and parsing them.

James, I tried Brian's method, but know (just as Brian said) that it checks /etc/redhat-release file. Just before I tried that method of subscription-manager above, I manually changed my /etc/redhat-release system on my test victim workstation to 6.7, and the output of the command gave 6.7. (and I changed the /etc/redhat-release file back)

James,

As I mentioned in the example code earlier in this discussion, I personally use an rpm query because as mentioned it has for me and my environment been the safest bet . To avert having to first query if it is centos or redhat, one could do the following:
(Perhaps the idea of "QUERYFMT" Tom brought up may refine this further...)

NOTE: check case sensitivity of "centos" below...

rpm -q {centos,redhat}-release-{server,workstation,5Client,5Server} | grep -v  'not installed'

That one-command bit above was able to successfully query my RHEL 5 and 6 servers and workstations. I suppose and believe there is a more elegant way to do this... but I have some systems to build

When I get home, I can add the bits for RHEL 7 to it, and centos as well.

Kind Regards

James,

I found these examples below at this link. I didn't include the examples that in some fashion parsed /etc/*-release because of the previously mentioned reasons...

[me@mysystem]# rpm -q --queryformat '%{VERSION}' $(rpm -qa '(redhat|sl|slf|centos|oraclelinux)-release(|-server|-workstation|-client|-computenode)')
[me@mysystem]# echo "or this"
[me@mysystem]# rpm -qa --qf '%{VERSION}' '(redhat|sl|slf|centos|oraclelinux)-release(|-server|-workstation|-client|-computenode)'

I tested this on a Centos 7 and RHEL 7, will check others

This averts having to first check what is providing /etc/*-release, and then turning around and then running the query against that rpm. This checks Red Hat, Scientific Linux, Centos, and even Oracle Linux (shudder). I'll check it tomorrow how this works for rhel 5 server/workstation.

Unfortunately Oracle Linux appears to complicate this method as on an Oracle Linux system you end up with multiple release packages, eg.

redhat-release-server-6Server-6.6.0.2.0.1.el6.x86_64
oraclelinux-release-6Server-6.0.2.x86_64

In this instance, the redhat-release rpm is essentially an empty dummy package that contains no files. The /etc/redhat-release file is owned by the oraclelinux-release package. So I believe it would still be safer to first validate what owns /etc/redhat-release and work back through RPMs from there.

I thought I'd mention it here for completeness, I appreciate this isn't an Oracle support forum... but some admins may be dealing with mixed environments.

Thanks Pixel for that good addition...

I do not use oracle Linux (and am glad).... But included it because of the source that I gave credit to.

Nice find Pixel,
Thanks

I have never understood why this numeric information is not provided simply by default in the various RHEL releases. There exist in fact all sorts of needs to be able to figure out stuff like "7.3", "6.8.0.5", "5.11.0.5" or even "10.3" (as is the case with certain RHEL 4 systems one may even today encounter).

Red Hat would do nicely if there was a routine which would always ensure this numeric information were provided in a file under /etc, such as "osnums" or whatever, in a way that would only require a simple read of the file without any additional hooplaa.

Based on a number of sources including this thread, I have come up with the following, although it may very well be improved by people with access to more systems or better insight. But shouldn't something like this be already in the installed and maintained OS, I think. Backporting such a simple routine at least to RHEL 5 and from there onwards ought not to be a major challenge, and would save a lot of time from people all over the globe.

8< -------

if [ -f /etc/redhat-release ]

then

    OS="RHEL"
    OSSTR="${OS} `cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*// | awk -F. '{ print $1 }'`"

    case $OSSTR in

            "RHEL 4")

                    rpm -q --qf '%{RELEASE}' $(rpm -qa '(redhat|sl|slf|centos|oraclelinux)-release(|-server|-workstation|-client|-computenode)') | sed -e 's/.el4/\n/g' -e 's/$/\n/g'
                    ;;

            "RHEL 5")

                    rpm -q --qf '%{RELEASE}' $(rpm -qa '(redhat|sl|slf|centos|oraclelinux)-release(|-server|-workstation|-client|-computenode)') | sed -e 's/.el5//g' -e 's/$/\n/g'
                    ;;

            "RHEL 6")

                    rpm -q --qf '%{RELEASE}' $(rpm -qa '(redhat|sl|slf|centos|oraclelinux)-release(|-server|-workstation|-client|-computenode)') | sed  -e 's/.el6/\n/g'
                    ;;

            "RHEL 7")

                    rpm -qa --qf '%{VERSION}' '(redhat|sl|slf|centos|oraclelinux)-release(|-server|-workstation|-client|-computenode)' | sed -e 's/$/\n/g'
                    ;;

            *)

                    echo "0.0.0.0"
                    ;;


    esac

fi

8< -------

  • that piece of code above could certainly be vastly improved upon.

$ python -mplatform Linux-2.6.32-696.23.1.el6.x86_64-x86_64-with-redhat-6.9-Santiago

I like it as it works on whatever has python on, I can grep out 'redhat' (as opposed to CentOS , Solaris or whatever) also the major / minor versions, as well as kernel version, it's all in one line, I don't have to decide on what file to open..

Suggestions:

$ rpm -qf /etc/issue
redhat-release-server-7.9-6.el7_9.x86_64
$

or, courtesy of the LibreNMS project:

$ curl -sL "https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro" | sh
Red Hat Enterprise Linux Server 7.9
$