前回紹介したスパムメールがさらに進化して「メアド変えたのでよろしく!」的な内容になってて、この人らPDCA実践してるわ―、と感心してしまったhiroshiです。
「3.レシピを書いたりする」の途中で終わった前回の続きです。
phpのインストールに必要なパッケージをインストールするところで終わっていましたので、次はphpのインストールです。
ここでphpをインストールする条件として
- インストールされてない
- 規定のバージョンと違う
- 想定のコンパイルオプションと違う
主なところはこんな感じです。
{chef-repo}cookbooks/php/recipes/default.rb
# バージョンのチェックを行い、バージョンが想定と違っていたらインストールを実行する
# サーバ稼働中の予期しないアップグレードを防ぐため、/usr/local/src/PHP_VERSION_CHECK_REQUIRED
# というファイルが存在する場合のみ処理が行われる。
buildtool_check_version "php" do
action :check
input '|/usr/local/bin/php -v'
regex /^PHP ([0-9.]+)/
version node[:php][:version]
only_if "cat /usr/local/src/PHP_VERSION_CHECK_REQUIRED"
notifies :create, "cookbook_file[/usr/local/src/#{node[:php][:tarball]}]", :immediately
notifies :install, "buildtool_make_install[php]", :immediately
pecl_packages.each do |package_name, install_name|
if node[:php][:extension][package_name.to_sym] then
notifies :run, "execute[pecl-install-#{package_name}-force]", :immediately
end
end
end
# PHPのコンパイルオプションが変わっている場合はインストールを実行する
# サーバ稼働中の予期しない再コンパイルを防ぐため、/usr/local/src/PHP_VERSION_CHECK_REQUIRED
# というファイルが存在する場合のみ処理が行われる。
# ただしPHPがインストールされていない場合は必ずインストールが実行される。
file "/usr/local/src/PHP_CONFIG_OPTION" do
content node[:php][:config_option]
only_if "cat /usr/local/src/PHP_VERSION_CHECK_REQUIRED || ! /usr/local/bin/php -v"
notifies :create, "cookbook_file[/usr/local/src/#{node[:php][:tarball]}]", :immediately
notifies :install, "buildtool_make_install[php]", :immediately
end
cookbook_file "/usr/local/src/#{node[:php][:tarball]}" do
action :nothing
source node[:php][:tarball]
mode "0644"
end
buildtool_make_install "php" do
action :nothing
tarball node[:php][:tarball]
srcdir "php-#{node[:php][:version]}"
config_option node[:php][:config_option]
notifies :restart, "service[httpd]"
end
4ブロックありますが、それぞれ以下の役割です。
- バージョンチェック
- コンパイルオプションチェック
- インストールファイルの展開
- インストール
最初のブロックのバージョンチェック部分からいってみます。
buildtool_check_version "php" do
とありますが、buildtool_check_versionは自前で定義したResourceです。
自前定義のResourceです。で終わるのもなんなので、ここでまた横道にそれてbuildtoolの説明をサックリしてみたいと思います。
buildtoolもcookbookのひとつです。
{chef-repo}/cookbook/buildtool/
に定義があります。
上述のbuildtool_check_versionについては、
{chef-repo}/cookbook/buildtool/resources/check_version.rb
actions :check # バージョンチェックをする Resource の定義 attribute :input, :kind_of => String, :required => true attribute :regex, :kind_of => Regexp, :required => true attribute :version, :kind_of => String, :required => trueとresourcesに定義をし
{chef-repo}/cookbook/buildtool/providers/check_version.rb
action :check do
begin
versionstring = IO.read(new_resource.input)
if new_resource.regex =~ versionstring
version = $1
if version != new_resource.version
Chef::Log.info("Version check for #{new_resource.name}: expected=#{new_resource.version}, actual=#{version}")
new_resource.updated_by_last_action(true)
end
else
Chef::Log.info("Version check failed: '#{versionstring}' is not match #{new_resource.regex}")
new_resource.updated_by_last_action(true)
end
rescue
Chef::Log.info("Version check failed: #{$!}")
new_resource.updated_by_last_action(true)
end
end
とprovidersに実際の動作を記述します。providersにあるnew_resourceにはresourcesで定義したattributeがあり、その中身は
buildtool_check_version "php" do action :check input '|/usr/local/bin/php -v' #ココ! regex /^PHP ([0-9.]+)/ #ココ! version node[:php][:version] #ココ!と、利用時に指定した値が入ります。
このあたりの構成が分かれば、check_version.rbが何しているかはrubyがわからなくてもなんとなくわかるかと思います。ぼくもrubyわかんないし。
ちなみに最後の
version node[:php][:version]は
{chef-repo}cookbooks/php/attributes/default.rb
default[:php][:version] = "5.x.x" default[:php][:tarball] = "php-" + default[:php][:version] + ".tar.bz2" default[:php][:config_option] = "--with-libdir=lib64 \ ~後略~
とここに書いた値が基本的には入ります。node[]で取れるの値ですが、設定できる場所は複数箇所あって優先順位があるので気をつけてください。詳しくは公式のこの辺を参照してみてください。
あと、気づいた人もいると思いますが、このbuildtool自体もRecipeの1つなのでbuildtool_check_versionをここで使うには、事前に
include_recipe "buildtool"しておく必要があります。
と、横道にそれてたら、このブロックの最初の5行まで追えたので次は
only_if "cat /usr/local/src/PHP_VERSION_CHECK_REQUIRED"
ですね。
これはこのブロックのコメントに書いてあるとおりです。
いやー、コメントっていいですね!
ちなみにウチで「変数宣言」とかいうコメント書いたらグラウンド10週か腕立て200回させられるので注意してください。しかもグラウンド探すところからですからけっこうキツイです。
では、またまた続きは次回に!
