本ブログではアイフィリエイトによる収益を得ています。

[Ruby] Chefで”database”クックブックを使ってCentOSにPostgreSQLを構成する際にはまったこと

2014年5月5日月曜日

Ruby 開発

t f B! P L C

2013-10-21 20.28.59

猫と一緒にガジェットライフ♪ムチャ(@mutoj_rdm821)です。

Chefというのは、サーバー(主にLinux)の設定やミドルウェアのインストール及び構成などをRubyのコードで記述して自動化するプラットフォームです。今回はピンポイントではまった事を書くだけなので、もう少し詳しく知りたい方は以下の記事をご覧下さい。完璧にまとまっています。

chef-solo - Chefを読んで実行するための全知識 – Qiita

今回ご紹介するのは、databaseクックブックを使ってPostreSQLを構成しようとしたときにはまった事とその解決方法です。しかしながら、確認したところこの問題は2014年5月5日時点で既に修正されている(後述)ので、今だと発生しないと思います。とはいえ、せっかくなので記事にしておきます。



databaseクックブックとは

既にインストールされているPostgreSQL、MySQL、SQLServerに対して、ユーザーの追加・削除・権限付与、データベースの作成・削除、SQLの投入を行う事ができます。

それぞれのセットアップについては個々にクックブックが配布されています。



CentOS上でPostgreSQLを構成しようとするとエラー

レシピを書いて実行すると、以下のエラーが発生しました。

Chef::Exceptions::Package: packagelibpq-dev had an error: Chef::Exceptions::Package: No version s
pecified, and no candidate version available for libpq-dev

libpq-devというのは、Debian用のパッケージです。なぜかCentOSなのにこれを入れようとして、存在しないので落ちてしまっていました。

詳しく追っていくと、内部で別の”postgresql”というクックブックを呼び出していて、その中のrecipes/ruby.rbでエラーが起きているようでした。以下はchef(chef-solo)の出力をdebugにした時の内容です。

================================================================================
Error executing action `install` on resource 'package[libpq-dev]'
================================================================================
SystemExit
----------
exit

Cookbook Trace:
---------------
/tmp/chef-repo/site-cookbooks/postgresql/recipes/ruby.rb:54:in `rescue in from_file'
/tmp/chef-repo/site-cookbooks/postgresql/recipes/ruby.rb:24:in `from_file'
/tmp/chef-repo/cookbooks/database/recipes/postgresql.rb:20:in `from_file'
/tmp/chef-repo/xxxxxxxxxxxxxxxxxxxx/recipes/database.rb:14:in `from_file'

Resource Declaration:
---------------------
# In /tmp/chef-repo/site-cookbooks/postgresql/recipes/ruby.rb
~略~
Compiled Resource:
------------------
# Declared in /tmp/chef-repo/site-cookbooks/postgresql/recipes/ruby.rb:52:in `rescue in from_file'
package("libpq-dev") do
  action [:nothing]
  retries 0
  retry_delay 2
  package_name "libpq-dev"
  cookbook_name :postgresql
  recipe_name "ruby"
end

================================================================================
Recipe Compile Error in /tmp/chef-repo/xxxxxxxxxxxxxx/recipes/database.rb
================================================================================

SystemExit
----------
package[libpq-dev] (postgresql::ruby line 52) had an error: SystemExit: exit

Cookbook Trace:
---------------
47: resources("package[#{pg_pack}]").run_action(:install)
48: end
49: require 'rbconfig'
50: 
51:
52: package "libpq-dev" do
53: action :nothing
54>> end.run_action(:install)
55:
56: begin
57: chef_gem "pg"
58: rescue Gem::Installer::ExtensionBuildError => e
59: # Are we an omnibus install?
60: raise if RbConfig.ruby.scan(%r{(chef|opscode)}).empty?
61: # Still here, must be omnibus. Lets make this thing install!
62: Chef::Log.warn 'Failed to properly build pg gem. Forcing properly linking and retrying (omnibus fix)'
63: gem_dir = e.message.scan(%r{will remain installed in ([^ ]+)}).flatten.first
Relevant File Content:
----------------------
/tmp/chef-repo/site-cookbooks/postgresql/recipes/ruby.rb:
~略~

最後のCookbook Trace:の所を見ると、確かにlibpq-devを入れようとして落ちてます。Chefでは実行されているOSを判別することもできるのですが、ここでは判定が行われていませんでした。

※この問題自体は1年以上前に修正がコミットされていたようですが、mastarにマージされたのが2週間ほど前だったようです(;´∀`)



どう対処したか

エラーの部分だけを見ても分かりませんが、この前にpostgresqlを操作するためのRubyのライブラリ(gem)の”pg”をrequireしようとして、失敗した場合(インストールされていない場合)に該当コードに到達することが分かりました。

なので、自分で作ったレシピの方で先にpgをインストールしてしまえばOKでした。

しかし、このpgというgemはネイティブコードを含んでいて、インストール時にコンパイルが必要となります。そのためにオプションを与えてやらないといけません。具体的には”pg-config”というコマンドへのパスです。

書いたレシピが以下の内容です。

pg_config_path = "/usr/pgsql-#{node['postgresql']['version']}/bin/pg_config"
require 'rbconfig'
gem_package "pg" do
  gem_binary "#{RbConfig::CONFIG['bindir']}/gem"
  options("-- --with-pg-config=#{pg_config_path}")
  action :install
end

パスの探し方は、別の何かのクックブックを参考にしてこのようにしました。

gem_packageリソースのオプションで、gem_binaryとoptionsを指定しています。

「先にpg入れておけばいいじゃん」と思うかもしれませんが、chefが実行に使うRubyの環境は専用に保持していて、普通にログインしてgemコマンドでインストールしても効果はありません。まあそのchef用環境(CentOSだと/var/opt/chef/以下だったか)に対してインストールすればよいのですが、それだとchefで構成する意味が無くなってしまいます。

Chefの公式コミュニティで配布されているクックブックはこうした小さなバグがあって、しかも長いこと放置されているものもあったりで大変でした。

次回はappilcation_javaというクックブックで遭遇した問題について書こうと思います。

それではみなさまよきガジェットライフを(´∀`)ノ



▼ブログを気に入っていただけたらRSS登録をお願いします!
▼ブログランキング参加中!応援よろしくお願いします。

ブログ内検索

自己紹介

猫とガジェットが好きなJava屋さんです。うつ病で休職後退職し、1年半の休養後に社会復帰。・・・が、いろいろあって再び退職。さらに1年休職の後に復帰して、なんとかSE続けてます。茶トラのすずと一緒に生活していましたが、2014年9月4日に亡くなって1人に。

より詳細なプロフィールはこちら↓

↓更新情報を受け取るにはフォローをお願いします!

Instagramでフォロー

※ヘッダー及びアイコンで使用しているドロイド君は、googleが作成、提供しているコンテンツをベースに複製したものです。

▼ココナラでメンターサービスを販売しています。招待コード「C3VG3」で1000ポイントもらえます。
▼欲しい物リスト

ブログ アーカイブ

QooQ