Embracing the Messiness in Search of Epic Solutions

Puppet: Installing Multiple Java Versions On Single Node

PROBLEM

I couldn’t find an existing Puppet module that allows me to install multiple Java versions on a single node. The reason for multiple Java versions is to allow Jenkins’s jobs to choose what Java version to compile with.

So, I will show you how to create a Puppet module that will do just that.

PREREQUISITES

The Puppet file structure should look like this:-

/etc/puppet/
├── hiera.yaml
├── manifests
│   └── site.pp
├── modules
│   ├── apt
│   └── stdlib
├── puppet.conf
└── templates

If you don’t have /etc/puppet/hiera.yaml, create one. Otherwise, you will get this annoying warning message:

Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults

My /etc/puppet/hiera.yaml looks like this:-

---
:backends:
  - yaml

:logger: console

:hierarchy:
  - "%{operatingsystem}"
  - common

:yaml:
   :datadir: /etc/puppet/hieradata

CREATING JAVA MODULE

Now, we are ready to create a Java module.

/etc/puppet/
├── hiera.yaml
├── manifests
│   └── site.pp
├── modules
│   ├── apt
│   ├── java
│   │   ├── files
│   │   │   └── java.preseed
│   │   └── manifests
│   │       └── init.pp
│   └── stdlib
├── puppet.conf
└── templates

Creating /etc/puppet/modules/java/files/java.preseed

The preseed file contains the responses needed to programmatically configure the package. In this module, I configured all the responses needed to install Java 6, 7 and 8.

oracle-java6-installer	shared/present-oracle-license-v1-1    note
oracle-java6-installer	oracle-java6-installer/local          string
oracle-java6-installer	shared/accepted-oracle-license-v1-1   boolean   true


oracle-java7-installer  shared/present-oracle-license-v1-1    note
oracle-java7-installer  oracle-java7-installer/local          string
oracle-java7-installer  shared/accepted-oracle-license-v1-1   boolean   true

oracle-java8-installer  shared/present-oracle-license-v1-1    note
oracle-java8-installer  oracle-java8-installer/local          string
oracle-java8-installer  shared/accepted-oracle-license-v1-1   boolean   true

If you are wondering how I figured out these values, you can easily generate a response file by manually installing a package first.

Creating /etc/puppet/modules/java/manifests/init.pp

This is the actual script that will perform the following tasks:-

  • Remove all OpenJDK versions if they exist.
  • Install multiple Oracle Java versions.
  • Select a default Java version.

If none of the arguments are provided, this script will install Java 7 and set it as the default version.

class java (
  $versions = [7],
  $default_version = 7
) {

  include apt

  apt::ppa{ 'ppa:webupd8team/java': }

  each( [6,7,8] ) | $version | {
    package { ["openjdk-${version}-jdk", "openjdk-${version}-jre"]:
      ensure => 'purged',
    }
  }

  file { "/tmp/java.preseed":
    source => "puppet:///modules/java/java.preseed",
    mode   => '0600',
    backup => false,
  }

  each( $versions ) | $version | {
    package { "oracle-java${version}-installer":
      responsefile => "/tmp/java.preseed",
      require      => [
        Apt::Ppa['ppa:webupd8team/java'],
        File["/tmp/java.preseed"]
      ],
    }
  }

  exec{ "update-java-alternatives -s java-${default_version}-oracle":
    path    => ["/usr/bin", "/usr/sbin"],
    require => Package["oracle-java${default_version}-installer"],
  }
}

Creating /etc/puppet/manifests/site.pp

In this example, we will install Java 6, Java 7 and Java 8. Further, we will set Java 7 to be the default version.

node default {
  class { 'java':
    versions        =>; [6,7,8],
    default_version => 7,
  }
}

TESTING

By specifying –noop, Puppet will execute the script in dry-run mode without applying the changes. This is very useful to catch any syntax errors before running the script for real. Since this script uses lambdas, we need to add –parser future option.

ubuntu@test:/$ sudo puppet apply --parser future --noop /etc/puppet/manifests/site.pp
Notice: Compiled catalog for test.mayo.edu in environment production in 1.32 seconds
Notice: /Stage[main]/Java/Package[oracle-java6-installer]/ensure: current_value absent, should be present (noop)
Notice: /Stage[main]/Java/Package[oracle-java8-installer]/ensure: current_value absent, should be present (noop)
Notice: /Stage[main]/Java/Package[oracle-java7-installer]/ensure: current_value absent, should be present (noop)
Notice: /Stage[main]/Java/Exec[update-java-alternatives -s java-7-oracle]/returns: current_value notrun, should be 0 (noop)
Notice: Class[Java]: Would have triggered 'refresh' from 4 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 1.57 seconds

EXECUTION

To apply the changes on the node, simply remove –noop.

ubuntu@test:/$ sudo puppet apply --parser future /etc/puppet/manifests/site.pp
Notice: Compiled catalog for test.mayo.edu in environment production in 1.31 seconds
Notice: /Stage[main]/Java/Package[oracle-java6-installer]/ensure: created
Notice: /Stage[main]/Java/Package[oracle-java8-installer]/ensure: created
Notice: /Stage[main]/Java/Package[oracle-java7-installer]/ensure: created
Notice: /Stage[main]/Java/Exec[update-java-alternatives -s java-7-oracle]/returns: executed successfully
Notice: Finished catalog run in 97.06 seconds

VERIFICATION

First, we check if all 3 Java versions are installed.

ubuntu@test:/$ ls -la /usr/lib/jvm/
total 32
drwxr-xr-x  5 root root 4096 Mar  2 17:59 .
drwxr-xr-x 63 root root 4096 Mar  2 17:59 ..
drwxr-xr-x  8 root root 4096 Mar  2 17:58 java-6-oracle
-rw-r--r--  1 root root 2430 Mar  2 17:58 .java-6-oracle.jinfo
drwxr-xr-x  8 root root 4096 Mar  2 17:59 java-7-oracle
-rw-r--r--  1 root root 2583 Mar  2 17:59 .java-7-oracle.jinfo
drwxr-xr-x  8 root root 4096 Mar  2 17:59 java-8-oracle
-rw-r--r--  1 root root 2481 Mar  2 17:59 .java-8-oracle.jinfo

Finally, we check if the right default Java version is set.

ubuntu@test:/$ java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
ubuntu@test:/$ javac -version
javac 1.7.0_51

Tags:

Comments

One response to “Puppet: Installing Multiple Java Versions On Single Node”

  1. Skúli Arnlaugsson (@Arnlaugsson) Avatar

    This looks perfect! Thanks for a great writeup!

Leave a Reply