最近ChefとServerspecを始めたので、備忘録としてメモを記載。
なるべくbash
やexecute
以外の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を実行するための設定
- 環境変数http_proxyにプロキシ情報を設定
export http_proxy=http://<ユーザID>:<パスワード>@<プロキシホスト>:<ポート番号>
- 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
パッケージのアンインストール→インストール
yum
のruby
が古いので、アンインストール後に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_ruby
はtrue
となる。
このページにあるように、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にリネーム
コピーした後に元のファイルを消すしかない?それかexecute
でmv
を実行するか。
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-*.*/bin
をPATH
に追加する。(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}