半歩進むChef-Solo - Cookbookの共通化(library)
Cookbookの共通化(library)
前回エントリではrecipeとdefinitionを用いたCookbookの共通化の手順を紹介しました。 今回はChefのもうひとつの共通化の仕組みであるlibraryを紹介します。
libraryって
libraryはRubyコードを用いて、Chefに新しいクラスやメソッドを追加することができる仕組みです。
libraryはクックブック内のlibraries/library_name.rbに定義することで自動で読み込まれ、recipes, attributes, file, definitions, providers, definitionsで利用することができます。
libraryの用途は以下の様なものがあります。
- ファイルに格納されている属性値へのアクセス
- ループのようなプログラムテクニックの利用
- Chefのレシピから直接呼び出せるような独自名前空間の作成(Chef::Recipeの名前空間をきれいな状態に保つ)
- データベースへの接続
- LDAPプロバイダとの接続
- その他、Rubyでできることはなんでも
libraryを使う
基本
1. libraryを定義する
一番かんたんな利用法は、Chef::Recipeクラスにメソッドを追加する方法です。 例としてChefのキャッシュディレクトリを取得するメソッドを定義してみます。
libraries/cache.rb
def cache_path
Chef::Config[:file_cache_path]
end
マニュアルではChef::Recipeクラスに明示的に定義するようになっていますが、上記の記法でもChef::Recipeクラスに定義されるようです。
2. libraryを使う
レシピ内などで呼び出すことができます。
recipes/default.rb
remote_file "#{cache_path}/sample.tar.gz" do
# 省略
end
名前空間
libraryが大きくなるようであれば、名前空間の分割を考える必要があります。 以下のようにChef::Recipe::XXXのように名前空間を分けて定義するか、後述のmodule化を検討してください。
libraries/cache.rb
class Chef::Recipe::Cache
def self.path
Chef::Config[:file_cache_path]
end
end
recipes/default.rb
remote_file "#{Cache.path}/sample.tar.gz" do
# 省略
end
module構成
名前空間の分割にはmoduleを利用することもできます。 opscodeでの利用例はmodule構成にして、helperとして定義する例が多いようです。
libraries/helper.rb
module Helper
def cache_path
Chef::Config[:file_cache_path]
end
end
recipes/default.rb
# moduleのinclude
::Chef::Recipe.send(:include, Helpers)
# メソッドを利用する
remote_file "#{cache_path}/sample.tar.gz" do
# 省略
end
attirubuteへのアクセス
マニュアルにはChef::Recipeクラスの@node変数経由で取得する記述になっていますが、通常通りnode.attr
もしくはnode[attr]
の取得方法で取得することができます。
resourceの利用
library内でもresource類を使うことができます。
前回のrecipe, definitionに続き、共通化という観点でlibraryを紹介しました。
次回はdefinition利用時のtipsを紹介する予定です。