2013-10-16 85 views
1

我想安裝一系列我的食譜所需的寶石,但我寧願不安裝開發工具(即gcc,gcc-C++,ruby-devel。更多上下文請參閱this )在我的生產機器上,所以在我的食譜中包含了相關的gem文件作爲資源。廚師安裝系列預包裝的寶石

我使用此代碼

node["chef_gems"].each do |pkg, attrs| 
    gem_file = "#{pkg}-#{attrs["version"]}.gem" 
    dest_gem_file = "#{Chef::Config['file_cache_path']}/#{gem_file}" 
    cookbook_file "#{dest_gem_file}" do 
     source "gems/#{gem_file}" 
    end 
    if File.exist?("#{dest_gem_file}") 
    chef_gem pkg do 
     source "#{dest_gem_file}" 
     action :install 
    end 
    end 
end 

問題,我在來

  1. 目前這需要兩個廚師運行運行,因爲File.exist的?檢查但沒有它,編譯失敗,因爲該文件在編譯階段不存在。有沒有更簡單的方法來實現這一點?
  2. 其中一些寶石具有依賴性,因此排序似乎默認爲按字母順序排列的事項。我正要通過一個排序順序鍵(醜陋的)來執行順序,想知道是否有更好的方法。
  3. 退一步,這似乎過於複雜。是否有一個更簡單的策略來實現安裝gem及其依賴項的目標,而無需在生產服務器上安裝開發工具。

這裏是沒有File.exist的原始錯誤?檢查

Starting Chef Client, version 11.4.0 
resolving cookbooks for run list: ["cis-rhel", "ec2-hostname-rhel", "chef-client", "cassandra"] 
Synchronizing Cookbooks: 
<REDACTED> 
Compiling Cookbooks... 
[2013-10-16T18:45:01-04:00] WARN: Cloning resource attributes for user[<REDACTED>] from prior resource (CHEF-3694) 
<REDACTED> 
[2013-10-16T18:45:01-04:00] WARN: Current user[cassandra]: /var/chef/cache/cookbooks/cassandra/recipes/user.rb:23:in `from_file' 
Recipe: cassandra::packages 
    * chef_gem[cassandra-cql] action install 
================================================================================ 
Error executing action `install` on resource 'chef_gem[cassandra-cql]' 
================================================================================ 


Gem::Exception 
-------------- 
Cannot load gem at [/var/chef/cache/cassandra-cql-1.1.4.gem] in/


Cookbook Trace: 
--------------- 
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb:36:in `block in from_file' 
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `each' 
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `from_file' 
/var/chef/cache/cookbooks/cassandra/recipes/default.rb:23:in `from_file' 


Resource Declaration: 
--------------------- 
# In /var/chef/cache/cookbooks/cassandra/recipes/packages.rb 

36:  chef_gem pkg do 
37:  source "#{dest_gem_file}" 
38:  action :install 
39:  end 
40: # end 



Compiled Resource: 
------------------ 
# Declared in /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:36:in `block in from_file' 

chef_gem("cassandra-cql") do 
    provider Chef::Provider::Package::Rubygems 
    action [:install] 
    retries 0 
    retry_delay 2 
    package_name "cassandra-cql" 
    source "/var/chef/cache/cassandra-cql-1.1.4.gem" 
    cookbook_name "cassandra" 
    recipe_name "packages" 
end 




================================================================================ 
Recipe Compile Error in /var/chef/cache/cookbooks/cassandra/recipes/default.rb 
================================================================================ 


Gem::Exception 
-------------- 
chef_gem[cassandra-cql] (cassandra::packages line 36) had an error: Gem::Exception: Cannot load gem at [/var/chef/cache/cassandra-cql-1.1.4.gem] in/


Cookbook Trace: 
--------------- 
    /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:36:in `block in from_file' 
    /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `each' 
    /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `from_file' 
    /var/chef/cache/cookbooks/cassandra/recipes/default.rb:23:in `from_file' 


Relevant File Content: 
---------------------- 
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb: 

29: node["cassandra"]["chef_gems"].each do |pkg, attrs| 
30: gem_file = "#{pkg}-#{attrs["version"]}.gem" 
31: dest_gem_file = "#{Chef::Config['file_cache_path']}/#{gem_file}" 
32: cookbook_file "#{dest_gem_file}" do 
33:  source "gems/#{gem_file}" 
34: end 
35: # if File.exist?("#{dest_gem_file}") 
36>>  chef_gem pkg do 
37:  source "#{dest_gem_file}" 
38:  action :install 
39:  end 
40: # end 
41: end 
42: 
43: # Some distributed packages of Cassandra start the service in their 
44: # postinstall; keep them all equal and a restart can be done after the configs 
45: # are written on the first run. Added difficulty: they also come with init 



[2013-10-16T18:45:01-04:00] ERROR: Running exception handlers 
[2013-10-16T18:45:02-04:00] FATAL: Saving node information to /var/chef/cache/failed-run-data.json 
[2013-10-16T18:45:02-04:00] ERROR: Exception handlers complete 
Chef Client failed. 0 resources updated 
[2013-10-16T18:45:02-04:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out 
[2013-10-16T18:45:02-04:00] FATAL: Gem::Exception: chef_gem[cassandra-cql] (cassandra::packages line 36) had an error: Gem::Exception: Cannot load gem at [/var/chef/cache/cassandra-cql-1.1.4.gem] in/
+0

請不要忘記標記答案是正確的! :) – sethvargo

回答

1
  1. 你可以和應該跳過if File.exist?("#{dest_gem_file}")段,如上面的資源總是創建文件或引發異常。
  2. 使用可處理依賴關係的包管理器安裝這些可能是更好的選擇,如果可以的話。
  3. 如果無法通過rubygems程序包管理器執行此操作,因爲它需要編譯程序包的本機擴展,您可以考慮打包編譯的版本並使用系統程序包管理器來安裝它們。
+0

回覆:1.我想,但當我嘗試,我得到一個配方編譯錯誤,我相信因爲兩階段廚師處理(即它試圖編譯配方,並失敗,因爲該文件尚不存在,所以永遠不會進入創建它的執行階段)。添加if是什麼「固定」,但仍需要兩個廚師跑。如果您認爲我錯過了某些內容,並且以前的解釋沒有意義,我可以發佈該錯誤的詳細信息。 – travelingsultan

+0

不,我的錯誤 - chef_gem在食譜編譯階段之前/期間安裝了寶石,以便它們可以在配方中直接使用。這隻在你打算從廚師食譜中使用gem時纔有用,否則你應該使用'gem_package'資源(不需要'File.exist?'檢查)。 – borntyping

+0

我只在食譜期間需要這些,並期望你描述的行爲,但它在我描述的方式失敗,讓我恢復到該狀態(將需要一段時間),併發回錯誤,也許我誤解了原因 – travelingsultan