Java versions on Red Hat

27 views
Skip to first unread message

Aleksey Tsalolikhin

unread,
May 30, 2015, 7:06:40 PM5/30/15
to help-c...@googlegroups.com
Situation:  We have to make sure certain RHEL servers have certain versions
of Java.  Java version is currently specified as the version field in the RPM file
name from Oracle.  However the version that the RPM feeds to the RPM database
(when installed) is different!

Example
------------
File: jdk-7u45-linux.x64.rpm     
"rpm -qa" shows: jdk-1.7.0_60_fcs  (First Customer Shipment, basically version 1.0 of that version)

This breaks CFEngine's packages promises and Standard Library because version 
identifiers differ between the RPM-on-disk and the RPM-after-installation.

I see two possible solutions:
1. Use a two-part approach: check RPM database and install if needed.
2. Write my a custom package_method body just for Java on RHEL.
Might need several (since we have several package_method for RHEL).
Gah.
 
Any ideas? I'm sure I'm not the first OR the last to run into this issue.
Right now I'm inclined to go with 1 since I have it already.

Data:

Existing code base uses shell script to detect if JDK RPM is installed, so I started
out by eplacing it with native CFEngine code.  

I tear filename-based version string apart using regextract() and put it back together 
as the RPM-database-based version string.

There is no easy way to check if a package is installed using packages promises IIRC.  
I opened https://dev.cfengine.com/issues/7236 requesting packageexists() and
used returnszero(/bin/rpm -q jdk-ver).


{{{

bundle agent java(java_version)  # e.g. 7u45-linux
{

############################################################################
# Part I - check if the package is installed
############################################################################
classes:
        "ok" expression => regextract(
                                     "^([\d]+)u([\d]+).*$",   # number(s), u, number(s)
                                     $(java_version),
                                     "backrefs"
                                     );
     ok::
      "got_it"
          expression => returnszero ("/bin/rpm --quiet -q jdk-1.$(backrefs[1]).0_$(backrefs[2])", noshell);


  reports:
    got_it::
      "detected $(java_version)";

###########################################################################
# Part II - ensure the package is installed
###########################################################################
   
  packages:
    !got_it::
      "jdk"
        package_policy => "addupdate",
        package_method => rpm_version("/repo"),
        package_select => "==",
        package_version => "1.$(backrefs[1]).0_$(backrefs[2]",
        package_architectures => { "x64" }; # kernel is x86_64 but JDK RPM has x64 in the file name (or i586 for 32-bit)
}

}}}

Gah!

Best,
-at

--
Need CFEngine training?  Email trai...@verticalsysadmin.com

Aleksey Tsalolikhin

unread,
May 31, 2015, 7:47:49 PM5/31/15
to help-c...@googlegroups.com
Just thought of a more elegant solution:

Create a symlink to the RPM that will reconcile the vendor's filename with the RPM VERSION.

This leaves the original file there (so we can trace it back to the vendor's shipment) but CFEngine will now be able to find it.  

Example:

# ln -s jdk-7u45-linux.x64.rpm jdk-1.7.0_45.x86_64.rpm
# ls -l *45*
lrwxrwxrwx 1 root root        22 May 31 23:43 jdk-1.7.0_45.x86_64.rpm -> jdk-7u45-linux.x64.rpm
-rw-r--r-- 1 root root 122585894 Jul 17  2014 jdk-7u45-linux.x64.rpm
#

Now I can use a single "packages" promise.



Eystein Måløy Stenberg

unread,
Jun 1, 2015, 11:30:27 AM6/1/15
to help-c...@googlegroups.com
In 3.6 there is packagesmatching() which might be what you were looking
for:
https://docs.cfengine.com/latest/reference-functions-packagesmatching.html

Also, in 3.7 the new packages promise should eliminate your problem
because it will ask rpm for the name/version/arch of the file (from its
metadata) before it checks it against the installed database (so it's
independent of the file name).
> <mailto:trai...@verticalsysadmin.com>
>
>
>
>
> --
> Need CFEngine training? Email trai...@verticalsysadmin.com
> <mailto:trai...@verticalsysadmin.com>
>
> --
> You received this message because you are subscribed to the Google
> Groups "help-cfengine" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to help-cfengin...@googlegroups.com
> <mailto:help-cfengin...@googlegroups.com>.
> To post to this group, send email to help-c...@googlegroups.com
> <mailto:help-c...@googlegroups.com>.
> Visit this group at http://groups.google.com/group/help-cfengine.
> For more options, visit https://groups.google.com/d/optout.

--

Eystein

Aleksey Tsalolikhin

unread,
Jun 1, 2015, 5:00:54 PM6/1/15
to Eystein Måløy Stenberg, help-c...@googlegroups.com
On Mon, Jun 1, 2015 at 8:30 AM, Eystein Måløy Stenberg <eystein.mal...@cfengine.com> wrote:
In 3.6 there is packagesmatching() which might be what you were looking
for:
https://docs.cfengine.com/latest/reference-functions-packagesmatching.html

Yes, that's it!  Thanks, Eystein!  And what is the fourth argument that it takes, method_regex?  I read the linked documentation but still don't know what "method" is.

Also, in 3.7 the new packages promise should eliminate your problem
because it will ask rpm for the name/version/arch of the file (from its
metadata) before it checks it against the installed database (so it's
independent of the file name).

I bet that will solve a lot of problems for a lot of people (with a small added cost of disk I/O) -- certainly worthwhile IMO, especially since vendors don't always follow the RPM naming conventions.

Thanks!!
Reply all
Reply to author
Forward
0 new messages