chef

Chefのメモ(ファイルコピー、環境変数、パッケージ)

More than 3 years have passed since last update.

最近ChefとServerspecを始めたので、備忘録としてメモを記載。

なるべくbashexecute以外のResourcesを書く方向で。


未解決


追加したyumリポジトリを参照しない場合がある

rpmforgeを追加してgitをインストールする。

include_recipe 'yumrepo::rpmforge'

# git-1.7.12.4-1がインストールされる
package "git" do
action :install
end

古いgitをアンインストールして、その後にgitをインストールする。

# git-1.7.1-3をアンインストール

yum_package "git < 1.7.10" do
action :remove
end

include_recipe 'yumrepo::rpmforge'

# rpmforgeではなくbaseを見て、git-1.7.1-3がインストールされる
package "git" do
action :install
end

リポジトリ追加を最初にするとgit-1.7.12.4-1がインストールされる。

include_recipe 'yumrepo::rpmforge'

# git-1.7.1-3をアンインストール
yum_package "git < 1.7.10" do
action :remove
end

# git-1.7.12.4-1がインストールされる
package "git" do
action :install
end

素直にaction :upgradeを使えばいいんですが、理由がよく分からなかったのでメモとして記載。最初にyum_packageを実行したタイミングで、以降に使用するリポジトリが固定されてしまうのかな?

include_recipe 'yumrepo::rpmforge'

# git-1.7.12.4-1がインストール/アップデートされる
package "git" do
action :updrade
end


解決済み


認証の必要なプロキシ経由でberkshelfを実行するための設定


  1. 環境変数http_proxyにプロキシ情報を設定

export http_proxy=http://<ユーザID>:<パスワード>@<プロキシホスト>:<ポート番号>


  1. open-uri.rbを編集

# open-uri.rbの161行目付近(OpenURI.open_loopメソッドの先頭)

options = {:proxy_http_basic_authentication => ["プロキシホスト", "ユーザID", "パスワード"] }


remote_fileのキャッシュ

 remote_fileリソースで、Chef::Config['file_cache_path'](/var/chef/cache/remote_file)にダウンロードして、2回目以降はキャッシュを使用するようにする。

remote_file "#{Chef::Config['file_cache_path']}/git-#{git['version']}.zip" do

source git['url']
mode 0644
not_if "test -f #{Chef::Config['file_cache_path']}/git-#{git['version']}.zip"
end


パッケージのアンインストール→インストール

 yumrubyが古いので、アンインストール後にcheckinstallで作成したrpmをインストールしようとした際に少しハマったのでメモ。

・失敗例:ruby-2.1.0のインストールに失敗

# ruby-1.8.7がインストールされており、アンインストールされる

yum_package "ruby < 1.9.2" do
action :remove
end

# rubyがインストールされている場合はtrue、されていない場合はfalse
is_installed_ruby = ( /^ruby/ =~ `rpm -q ruby` ) ? true : false

if is_installed_ruby
log "ruby is installed."

else
cookbook_file "/tmp/ruby-2.1.0-1.x86_64.rpm" do
source "ruby-2.1.0-1.x86_64.rpm"
end

rpm_package "ruby" do
source "/tmp/ruby-2.1.0-1.x86_64.rpm"
action :install
end
end

・実行結果

(中略)

[2014-04-02T01:08:17+09:00] WARN: yum_package[ruby < 1.9.2] matched multiple Provides for ruby < 1.9.2 but we can only use the first match: ruby. Please use a more specific version.
[2014-04-02T01:08:18+09:00] INFO: yum_package[ruby < 1.9.2] removed
[2014-04-02T01:08:18+09:00] INFO: ruby is installed.
(中略)

 上記の通り、rubyはアンインストールされるが、is_installed_rubytrueとなる。

 このページにあるように、rubyスクリプトの処理が最初に行われ、次にリソースの処理が行われる。そのため、is_installed_rubyはレシピ開始時点での状態で評価され、yum_packageの処理結果と関係なくtrueになる。

 本来の意図である、rubyをアンインストールしてからインストールする場合には、リソースの中に条件を記載する必要がある。

yum_package "ruby < 1.9.2" do

action :remove
end

log "ruby is installed." do
only_if { /^ruby/ =~ `rpm -q ruby` }
end

cookbook_file "/tmp/ruby-2.1.0-1.x86_64.rpm" do
source "ruby-2.1.0-1.x86_64.rpm"
not_if { /^ruby/ =~ `rpm -q ruby` }
end

rpm_package "ruby" do
source "/tmp/ruby-2.1.0-1.x86_64.rpm"
action :install
not_if { /^ruby/ =~ `rpm -q ruby` }
end

・実行結果

(中略)

[2014-04-02T01:33:31+09:00] WARN: yum_package[ruby < 1.9.2] matched multiple Provides for ruby < 1.9.2 but we can only use the first match: ruby. Please use a more specific version.
[2014-04-02T01:33:32+09:00] INFO: yum_package[ruby < 1.9.2] removed
[2014-04-02T01:33:32+09:00] INFO: cookbook_file[/tmp/ruby-2.1.0-1.x86_64.rpm] created file /tmp/ruby-2.1.0-1.x86_64.rpm
[2014-04-02T01:33:35+09:00] INFO: cookbook_file[/tmp/ruby-2.1.0-1.x86_64.rpm] updated file contents /tmp/ruby-2.1.0-1.x86_64.rpm
(中略)

複数のリソースに同じ条件を記載するのは面倒なので、何か上手い方法はないものか。。。


ファイルのコピー、リネーム

レシピから転送するのはcookbook_fileでいいとして、対象のサーバ上のファイルをコピー、リネームする。(バックアップ等の用途)


ファイルのコピー

例)/etc/profileのコピー(/etc/profile.bak)

file "/etc/profile.bak" do

content IO.read("/etc/profile")
end


ファイルのリネーム

例)/etc/httpd/conf.d/welcome.confをwelcome.conf.bakにリネーム

コピーした後に元のファイルを消すしかない?それかexecutemvを実行するか。

file "/etc/httpd/conf.d/welcome.conf.bak" do

content IO.read("/etc/httpd/conf.d/welcome.conf")
end

file "/etc/httpd/conf.d/welcome.conf" do
action :delete
end


環境変数の設定

JBossを動作させるためにJAVA_HOMEを設定したり、gem install pgを実行するために、/usr/pgsql-*.*/binPATHに追加する。(pg_configのパスを通すため)

/etc/profile.dディレクトリ内にシェルを作成する。


環境変数の値がレシピに依存しない場合

JAVA_HOMEの値はreadlink -m $(which java)で取得できるので、cookbook_fileで静的ファイルを転送する。

・recipe

cookbook_file "profile-java.sh" do

path "/etc/profile.d/java.sh"
end

・files/default/profile-java.sh

JAVA_PATH=`readlink -m $(which java)`

export JAVA_HOME=${JAVA_PATH%/*/*}


環境変数の値がattributes等に依存する場合

パスが/usr/pgsql-*.*/bin(.はバージョン)の場合、バージョンはパラメータによって変わるのでtemplateで転送する。

レシピの中でシェルコマンドでpg_configのパスを取得して、その値をtemplateから参照したりできるんですかね・・・?

・recipe

# 9.2の場合、/etc/profile.d/postgresql92.shを作成

template "/etc/profile.d/postgresql#{short_version}.sh" do
source "profile-postgresql.sh.erb"
end

・templates/default/profile-postgresql.sh.erb

# PATHに/usr/pgsql-9.2/binを追加

PGSQL_PATH=/usr/pgsql-<%= node['postgresql']['version'] %>/bin
export PATH=$PATH:${PGSQL_PATH}