chefで2つのレシピで共通のファイルをtemplateで定義した場合。例えばrubyとnodeのレシピがあった場合に、どちらのレシピでも.bash_profileを定義したいことがありました。
問題
それぞれのレシピで定義した「.bash_profile」を適用した場合、実行順で上書きされてしまいます。例えば、ruby、nodeのレシピの順で実行した場合、nodeのレシピが適用されてしまいます。
解決方法
こうした時にいくつか方法が考えられます。
- 別々の.bash_profile_xxのようなファイルを作って、それを「.bash_profile」にsourceで読み込みます。それでそれぞれの読み込み設定が書かれていない場合は追記するコマンドを実行します。
- 別のレシピで管理する方法
今回は1の方法を試してみました。
やり方
recipeでは、「.bash_profile_xx.erb」というtemplateを定義しています。そして、grepして それぞれのファイルを読み込んでいるか確認し、読み込まれていない場合は「source ~/.bash_profile_xx.erb」を追記するようにしています。
site-cookbooks/ruby/recipe/default.rb
template ".bash_profile_ruby" do
source ".bash_profile_ruby.erb"
path "/home/#{node['ruby']['user']}/.bash_profile_ruby"
mode 0644
owner node['ruby']['user']
group node['ruby']['group']
not_if "grep rbenv ~/.bash_profile", :environment => { :'HOME' => "/home/#{node['ruby']['user']}" }
end
execute "update bash_profile" do
command "echo source /home/#{node['ruby']['user']}/.bash_profile_ruby >> /home/#{node['ruby']['user']}/.bash_profile; chmod 0644 /home/#{node['ruby']['user']}/.bash_profile"
only_if "test ! `grep bash_profile_ruby ~/.bash_profile | wc -l` -eq 0", :environment => { :'HOME' => "/home/#{node['ruby']['user']}" }
end
site-cookbooks/node/recipe/default.rb
template ".bash_profile_node" do
source ".bash_profile_node.erb"
path "/home/#{node['node']['user']}/.bash_profile_node"
mode 0644
owner node['node']['user']
group node['node']['group']
not_if "grep ndenv ~/.bash_profile_node", :environment => { :'HOME' => "/home/#{node['node']['user']}" }
end
execute "update bash_profile" do
command "echo source /home/#{node['node']['user']}/.bash_profile_node >> /home/#{node['node']['user']}/.bash_profile; chmod 0644 /home/#{node['node']['user']}/.bash_profile; exec $SHELL -l"
only_if "test ! `grep bash_profile_node ~/.bash_profile | wc -l` -eq 0", :environment => { :'HOME' => "/home/#{node['node']['user']}" }
end
templateでは特に珍しいようなことは書かいていません。こんな感じですね。
site-cookbooks/ruby/templates/.bash_profile_ruby.erb
# .bash_profile
# get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc;
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
site-cookbooks/node/templates/.bash_profile_node.erb
# .bash_profile
# get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc;
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH="$HOME/.ndenv/bin:$PATH"
eval "$(ndenv init -)"
今回はこのように定義しましたが、2の方がきれいにかけるので、今度試してみます。