Chefでbundlerなどのgemをinstallさせる
アプリケーションだけでなく、インフラ部分も触るのでその構築によくChefを使っているのですが、bundlerのinstallもChefでやろうとしたらなかなかinstallされずはまってしまったので解決方法とはまりポイントを共有です。
要約
はまりポイントを要約すると以下になります。
- 実行するコマンドはフルパスで書く
- executeを実行するユーザーは、userで指定したユーザーではない
rbenvがない??
最初に書いたrecipeは下記のようなものでした。
execute 'install bundle' do user node['rails']['user'] command <<-EOS gem install bundler -v 1.11.2 rbenv rehash EOS not_if "gem list | grep bundler" end
一見これで動きそうな気がするのですが、エラー。
STDERR: sh: rbenv: command not found
なにやら、rbenvがないと言われているようだ。
もちろん、ログインして実行するとrbenvがあるので、rbenvがないわけではない。
そこで、実行するコマンドに片っ端にパスを明記してみた。
#{rbenv_path}/shims/gem install bundler -v 1.11.2 #{rbenv_path}/bin/rbenv rehash
すると。。。
なぜか、シェルの実行ユーザーがrootになっている
---- STDOUT: Successfully installed bundler-1.11.2 Parsing documentation for bundler-1.11.2 Installing ri documentation for bundler-1.11.2 Done installing documentation for bundler after 3 seconds 1 gem installed STDERR: mkdir: cannot create directory ‘/root/.rbenv’: Permission denied
ん? gem のinstall はいいとして、なに?Permission deniedって。
しかも、/root
ってどういうこと??
なにが起きているのかさっぱりなので、コマンドを変更して、とりあえず環境変数を表示してみる。
command <<-EOS env exit 1 EOS
すると。。。
USER=root HOME=/root
なんと!! ユーザーがrootになってるではないか! userで指定してるユーザーはなんなんだ!?
そこで、調べてみると、chef の execute で bundle exec 実行するという記事をQiitaより発見。 記事によると、
execute の user を指定しても、HOME と USER 環境変数は更新されず、chef 実行ユーザの環境変数のままとなる。
なにそれ。。。
なぜそうなるのかはよく分からないが、とりあえずenvironment
でUSER
, HOME
を直接指定すればよいとのこと。
environment ({ 'USER' => user, 'HOME' => "/home/#{user}" })
早速、environment
を追加し、実行してみたところ。。。
無事、bundlerがinstallされました!!
完成系
いろいろ試行錯誤して出来上がったのは以下のようなファイルです。
user = node['rails']['user'] rbenv_path = "/home/#{user}/.rbenv" execute 'install bundle' do user user command <<-EOS #{rbenv_path}/shims/gem install bundler -v 1.11.2 #{rbenv_path}/bin/rbenv rehash EOS not_if "#{rbenv_path}/shims/gem list | grep bundler" environment ({ 'USER' => user, 'HOME' => "/home/#{user}" }) end