Category Archives: Ubuntu

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

Installing Puppet v3.2+ in Ubuntu

PROBLEM

By default, when using apt-get, Puppet v2.7 will be installed. This version doesn’t support useful features, such as Lambdas and iteration. To use these experimental features, Puppet v3.2+ is required.

SOLUTION

First, visit http://apt.puppetlabs.com/ and determine the matching Ubuntu version.

Let’s assume we are using Ubuntu 13.04 (Raring Ringtail). So, we will choose http://apt.puppetlabs.com/puppetlabs-release-raring.deb from the list.

Execute the following commands to install Puppet:-

wget http://apt.puppetlabs.com/puppetlabs-release-raring.deb
sudo dpkg -i puppetlabs-release-raring.deb
sudo apt-get update
sudo apt-get install puppet

Finally, run the following command to verify the installed version:-

puppet --version

The installed version should be v3.2+ and above.