Akom's Tech Ruminations

Various tech outbursts - code and solutions to practical problems
Linux

Maven toolchains and puppet

Posted by Admin • Monday, August 31. 2015 • Category: DevOps, Linux

For today's trick we'll be setting up maven toolchains.xml files on Jenkins slaves that are managed by puppet. One option for doing this is to use the Jenkins Config File Provider plugin - but all that really does is push a predetermined file to the slaves before running the job (now if it only worked together with the Jenkins tool provider data...) In our case, we have Jenkins slaves with different OS versions and thus different toolchain locations - for example, minor JDK releases differ across OS's and thus the paths are not the same.

Instead, the plan is to do two things:
  1. Create a puppet custom fact with installed tool info
  2. Use it from a puppet template
Here is how

First, the custom fact. Important note here is that if you're on an older puppet (say, 3.7), you need to make sure that stringify_facts is false on both the puppet master and agents, and that you bounced both! This fact returns an array of hashes, and if stringify_facts is true, you'll get a very ugly string instead.

Here is a basic implementation of a fact that loads info about the installed JDK's - this is for linux only, obviously:

# Looks for install JDKs in /usr/lib/jvm and sets them as an array of hashes: { "path" => dirpath, "vendor" => vendor, "version" => version }
#
Facter.add("java_versions") do
  setcode do

    result = []

    if File.exists?('/usr/lib/jvm') or File.exists?('/usr/lib64/jvm')
      cmd = 'find /usr/lib*/jvm -type f -name javac | grep -v jre | grep -E "[0-9]\.[0-9]" | sort | sed "s/^\(.*java-\([0-9]\.[0-9]\)\.[0-9].*\)\/bin\/javac$/\2 \1/"'
      output = %x( #{cmd} ).split("\n")


      output.each { |line|
        lineparts = line.split(" ")
        version = lineparts[0]
        dirpath = lineparts[1]
        vendor = "sun"

        if dirpath.match(/openjdk/)
          vendor = "openjdk"
        end

        result.push({"path" => dirpath, "vendor" => vendor, "version" => version})
      }
    end

    result
  end
end  

 
I would add support for other JDK vendors but I didn't have any to test on. Of course it would be more proper to use some complicated combination of querying rpm and alternatives, but in my testing these were both entirely unpredictable.

Now, let's use the information in a template:

<toolchains>
    <% @java_versions.each do |java_info| %>

    <toolchain>
        <type>jdk</type>
        <provides>
            <version><%=java_info['version']%></version>
            <vendor><%=java_info['vendor']%></vendor>
        </provides>
        <configuration>
            <jdkHome><%=java_info['path']%></jdkHome>
        </configuration>
    </toolchain>
   
    <% end %>

</toolchains>
 

0 Trackbacks

  1. No Trackbacks

0 Comments

Display comments as (Linear | Threaded)
  1. No comments

Add Comment


You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
Markdown format allowed


Submitted comments will be subject to moderation before being displayed.