« 2012年1月 | メイン | 2014年8月 »

2014年7月

2014年7月16日 (水)

Chef の database cookbook でハマった話

こんにちは、エンジニアの小笠原です。

最近は Chef で開発環境の構築なんかやってるわけですが、database cookbook の利用でハマったので小ネタ的に。
結論からいうと、rubyのコードくらい読めるようになっておこうね、という話でしかないんですが。。

前提

  • Heroku を使うことが多いので、RDBMS は基本 PostgreSQL
  • 開発環境もできるだけ構成を本番環境に合わせて構築したい
  • ローカル開発環境構築は基本 VirtualBox + Vagrant + Chef + Test-kitchen
  • DB のユーザ作ったりデータベース作ったりは database cookbook で出来る
  • 筆者は Ruby 経験ほぼなし

ハマったこと

postgresql cookbook での PostgreSQL の設定、database cookbook 使って稼働してる PostgreSQL への CREATE USER/GRANT, CREATE DATABASE 共に、それぞれ単体では問題なくできました。
が、双方を一緒に実行させようとするとエラーを吐いて止まります。

.kitchen.yml にはこう記述してる状態。

suites:
  - name: default
    run_list:
      - recipe[postgresql::server]
      - recipe[init_db]

init_db cookbook のレシピで、include_recipe database::postgresql して DB ユーザの生成なんかを記述してるわけですね。
で、kitchen setup すると、

(前略)
[2014-07-16T01:09:18+00:00] ERROR: Exception handlers complete
[2014-07-16T01:09:18+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
Chef Client failed. 15 resources updated in 711.501939185 seconds
[2014-07-16T01:09:18+00:00] ERROR: execute[generate pg gem Makefile] (postgresql::ruby line 89) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of PATH=$PATH:/usr/pgsql-9.3/bin /opt/chef/embedded/bin/ruby extconf.rb ----
STDOUT: checking for pg_config... no
checking for libpq-fe.h... no
STDERR: No pg_config... trying anyway. If building fails, please try again with
 --with-pg-config=/path/to/pg_config
Can't find the 'libpq-fe.h header
       *** extconf.rb failed ***
(後略)

と怒られました。

なんで単体で動いたものが組み合わせると動かなくなるん? Chef って記述した順にシーケンシャルに実行してくれるんじゃないの?とまったく Chef を理解してない感丸出しで調査スタート。

単体で動いてたものが組み合わせると動かなくなった謎については、Engine Yardさんのブログが紐解いてくれました。
単体で database cookbook 動かしてた時は既に postgresql cookbook のおかげでインストールされてた libpq が、組み合わせた場合はコンパイル(か run_action 実行)時にはまだインストールされてない為エラーになった、と。

さてじゃぁ、どうやってあらかじめ libpq をインストールすれば良いんだろう?と考えてもわからなかったので、仕方なくソースコードを読みます。
エラーの発生した箇所は、出力されてるログからわかります。

       Cookbook Trace:
       ---------------

         /tmp/kitchen/cookbooks/postgresql/recipes/ruby.rb:95:in `rescue in rescue in from_file'
         /tmp/kitchen/cookbooks/postgresql/recipes/ruby.rb:57:in `rescue in from_file'
         /tmp/kitchen/cookbooks/postgresql/recipes/ruby.rb:24:in `from_file'
         /tmp/kitchen/cookbooks/database/recipes/postgresql.rb:20:in `from_file'
         /tmp/kitchen/cookbooks/init_prj/recipes/default.rb:13:in `from_file'

ん? database cookbook って実際の DB の cookbook を呼び出してるのね。
まぁともかく追っていくと、postgresql/recipes/ruby.rb は、どうやら pg gem をビルドしてインストールするレシピのようですね。
で、95行目でエラーになってると。

    lib_builder = execute 'generate pg gem Makefile' do
      # [COOK-3490] pg gem install requires full path on RHEL
      command "PATH=$PATH:/usr/pgsql-#{node['postgresql']['version']}/bin #{RbConfig.ruby} extconf.rb"
      cwd ext_dir
      action :nothing
    end
    lib_builder.run_action(:run)

lib_builder.run_action(:run) が 95行目です。
んー、ということは、ここまでに libpq がインストールされれば良いと。
コードを遡って行くと、

  node['postgresql']['client']['packages'].each do |pg_pack|
    resources("package[#{pg_pack}]").run_action(:install)
  end

という記述を見つけました。
こいつは postgresql::client レシピでインストールするパッケージを指定する attribute じゃないですか。
というわけで、 .kitchen.yml に以下のように libpq-dev パッケージ(Ubuntu14.04)のインストール指定を追加したところ、無事エラーなく動いてくれました。

    attributes:
      postgresql:
        client:
            packages: ["libpq-dev", "postgresql-client-9.3"]

まとめ

  • Chefのレシピは上から下にシーケンシャルに実行されるわけじゃない
  • 困ったらソースコード読もう

続きを読む "Chef の database cookbook でハマった話" »

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上での
Webアプリケーション開発
エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、セールスフォースパートナーです。
また、heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。

2022年5月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
ブログ powered by TypePad