Help us understand the problem. What is going on with this article?

Chefのメモ(ファイルコピー、環境変数、パッケージ)

More than 5 years have passed since last update.

最近ChefとServerspecを始めたので、備忘録としてメモを記載。
なるべくbashexecute以外の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を実行するための設定

  1. 環境変数http_proxyにプロキシ情報を設定
export http_proxy=http://<ユーザID>:<パスワード>@<プロキシホスト>:<ポート番号>
  1. 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

パッケージのアンインストール→インストール

 yumrubyが古いので、アンインストール後に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_rubytrueとなる。
 このページにあるように、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にリネーム
コピーした後に元のファイルを消すしかない?それかexecutemvを実行するか。

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-*.*/binPATHに追加する。(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}
asam316
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away