execで異なるバージョンのMWをインストールする方法

Puppetアドベントカレンダー２３日目、微力ながら支援させていただきます。

以前、udzuraさんがexecのrefreshonlyの使い方をご説明していただきましたが、ここではexecを使用して異なるバージョンのMWをインストールする方法を紹介したいと思います。

MWを新しいバージョンにアップデートする！となった際、問題があったときに古いバージョンに戻せるように、古いバージョンを残したまま新規バージョンもインストールできたらうれしいですよね。MWによっては古いバージョンと共存できないものもあるかもしれませんが、こんなこともPuppetで出来るんだ〜と思っていただけたら幸いです。

今回は、異なるバージョンのOpenJDKをインストールしてみようと思います。
## 動作環境
　- Mac OS X 10.8.5
　- ruby 1.8.7
　- puppet-3.8.4,hiera-1.3.4,factor-2.4.4（※2015/12/23時点の最新パッケージを使用）

MacへのPuppetインストール時にちょっとハマったのでそれはまた別の機会に。。。

さて、まずは現在インストールされているOpenJDKのバージョンを確認します。
`/usr/libexec/java_home -V`

```lang:java_home
Matching Java Virtual Machines (2):
    1.6.0_65-b14-462, x86_64:	"Java SE 6"	/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_65-b14-462, i386:	"Java SE 6"	/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
```
現在、1.6.0_65がインストールされているため、それ以外のバージョンのOpenJDKをインストールする定義を作成したいと思います。
### OpenJDKインストール定義
単純にOpenJDKをインストールする定義はpackageリソースを使用して以下のように書けます。

```lang:openjdk_install.pp
class openjdk::install (
  $openjdk = '',
){
  package { 'openjdk':
    name   => $openjdk,
    ensure => installed,    
  }
}
```
ただ、特定のバージョンのMWをインストールする場合は、ソースからビルドする場合が多いかと思います。その場合の定義は以下のように書けます。

```lang:openjdk_install_src.pp
class openjdk::install_src (
  $openjdk_src = '',
){
  file { '/tmp/${openjdk_src}':
    ensure => present,
    owner  => root,
    group  => root,
    mode   => 0644,
    source => "puppet:///modules/openjdk/${openjdk_src}",    
  }

  exec { 'Expand ${openjdk_src}':
    command => "/bin/tar zxvf /tmp/${openjdk_src}",
    user    => 'root',
    cwd     => '/Library/Java',
    unless  => '/usr/bin/test -f /Library/Java/Home/bin/java',
    require => File['/tmp/${openjdk_src}'],
}
```
上記の定義によって任意のバージョンのOpenJDKをインストールできるようになりましたが、packageリソースでの定義同様、１バージョンのOpenJDKしかインストールできません。そこで、以前kijibatoさんに紹介していただいたHieraで同じリソースを複数定義する手法を使用するることで、複数バージョンのOpenJDKのインストールを実現します。

### 応用編（Hieraと組み合わせると）
まず、defineでOpenJDKインストールを定義します。

```lang:openjdk_def_install_src.pp
define openjdk::def_install_src (
  $openjdk_src = '',
){
  file { '/tmp/${openjdk_src}':
    ensure => present,
    owner  => root,
    group  => root,
    mode   => 0644,
    source => "puppet:///modules/openjdk/${openjdk_src}",    
  }

  exec { 'Expand ${openjdk_src}':
    command => "/bin/tar zxvf /tmp/${openjdk_src}",
    user    => 'root',
    cwd     => '/Library/Java',
    unless  => '/usr/bin/test -f /Library/Java/Home/bin/java',
    require => File['/tmp/${openjdk_src}'],
}
```
次に、上記で定義（define）したopenjdk_def_install_srcをcreate_resourcesで展開するクラスを用意します。

```lang:openjdk_resource_install_src.pp
class openjdk::resource_install_src (
){
  $resource_install_src = hiera_hash('openjdk::resource_install_src::hash',{})
  create_resources('openjdk::def_install_src',$resource_install_src)
}
```
あとは、Hieraで以下のように定義すれば複数の異なるバージョンのOpenJDKをインストールすることができます。

```lang:openjdk_install_sample.yaml
---
classes:
  - openjdk::resource_install_src

openjdk::resource_install_src::hash:
  1.6.0:
    openjdk_src: 'openjdk-1.6.0'
  1.7.0:
    openjdk_src: 'openjdk-1.7.0'
```
ちょっと動作確認ができていないため、上記の定義できちんと動作するか確認が必要ですが、このように定義することで複数バージョンのMWのインストールをPuppetで実現できます。