2015-05-21 56 views
0

我有用於安裝JRuby的社區主廚食譜。我無法指定要安裝的Gem版本。我真的嘗試了我能想到的各種哈希,鍵,字符串等組合。如何在散列中指定參數

下面是代碼的相關部分:

default[:jruby][:gems] = ["some-gem", "another-one"] 

是的,這是一個字符串數組,但哈希值的陣列應該是可能的。

這是由下面的代碼片段閱讀:

node[:jruby][:gems].each do |gem| 
    Chef::Log.info "Installing Jruby Gem #{gem}" 
    if gem.is_a? Hash 
    name = gem.delete(:name) 
    else 
    name = gem 
    gem = nil 
    end 
    jruby_gem name, gem || {} 
end 

而在本定義的手結束了:

define :jruby_gem, :source => nil, :version => nil do 
    gem_package params[:name] do 
    gem_binary "#{node[:jruby][:install_path]}/bin/gem" 
    source params[:source] if params[:source] 
    version params[:version] if params[:version] 
    end 
end 

鑑於代碼,將填補什麼哈希散列的:name:version最終定義中的值?

事情我已經試過在以下領域...

[ 
    {:name => "some-gem", :version => "0.1.2"}, 
    {:name => "another-one"} # I don't need to constrain every Gem to a version 
] 

編輯:

所以謝謝你的完全正確的Ruby式的反應,但實際上我曾嘗試的陣列在轉向SO之前,散列方法在一些變體中。疲勞讓我錯了最初出現在我的問題中的結構。

我看到的問題似乎涉及廚師和您在上面看到的定義。錯誤我得到的是如下...

Node attributes are read-only when you do not specify which precedence level to set. To set an attribute use code like `node.default["key"] = "value"' 

    Cookbook Trace: 
    --------------- 
    /var/chef/cache/cookbooks/jruby/recipes/default.rb:48:in `block in from_file' 
    /var/chef/cache/cookbooks/jruby/recipes/default.rb:45:in `each' 
    /var/chef/cache/cookbooks/jruby/recipes/default.rb:45:in `from_file' 

    Relevant File Content: 
    ---------------------- 
    /var/chef/cache/cookbooks/jruby/recipes/default.rb: 

    41: notifies :create_if_missing, "file[/etc/profile.d/jruby.sh]" 
    42: end 
    43: 
    44: # install all gems defined in the module 
    45: node[:jruby][:gems].each do |gem| 
    46: Chef::Log.info "Installing Jruby Gem #{gem}" 
    47: if gem.is_a? Hash 
    48>>  name = gem.delete(:name) 
    49: else 
    50:  name = gem 
    51:  gem = nil 
    52: end 
    53: jruby_gem name, gem || {} 
    54: end 
    55: 
+1

'[「一些寶石」,「另一條」]'是一個數組,而不是一個哈希...... – user12341234

+0

這是一個很好的點。這是我累了的功能,而不是我的愚蠢。 :) –

回答

1

不幸,這裏的問題不是你的屬性,而是你的實際食譜。

您(和我,今天!)使用的jruby cookbook的實現與Chef 11+不兼容。請參閱此鏈接:

https://www.chef.io/blog/2013/02/05/chef-11-in-depth-attributes-changes/

現在必須指定你想要寫設置屬性時,其優先級;直接訪問節點上的屬性僅用於讀取。

其在這裏示數的線是做正是:

if gem.is_a? Hash 
    name = gem.delete(:name) <- This is modifying node.jruby.gems.some_gem! 

如果你想利用這一點,因此,你必須做採取的一些方法之一:

  1. 把jruby cookbook分叉並修復它。這是非常古老的,現有的直接分支都不支持11號廚師,所以如果你想接管它,你可以變得像一個小小的神。
  2. 你的寶石裝置完全使用單獨的食譜(這是我們一直在做的事情)。
  3. 創建包裝的食譜,其中包括JRuby的食譜沒有設置jruby.gems,並添加自己的屬性和Ruby塊,設置的事情「正確」的方式。

一個例子是:

my_gems = node['jruby']['my_gems'].dup 

my_gems.each do |gem| 
    if gem.is_a? Hash 
    name = gem.delete('name') 
    else 
    name = gem 
    gem = nil 
    end 
    jruby_gem name, gem || {} 
end 

這將實際工作,給出的調整適量。使用這個確切的塊的一個例子廚師客戶端輸出爲:

> Recipe: mycompany-jruby::default 
> * gem_package[some-package] action install 
> - install version #.#.# of package some-package 
0

嘗試:

[ 
    {:name => "some-gem", :version => "0.1.2"}, 
    {:name => "another-one"} # I don't need to constrain every Gem to a version 
] 

注意,內部數據結構與大括號,而不是方括號定義。

  • []的製造陣列
  • {}「作一個哈希

你正在創造一個數組的數組,但你真正想要的是哈希值的數組。

編輯

該文檔似乎表明你可以嘗試沿着線的東西:

default[:jruby].set[:gems] = ["some-gem", "another-one"] 

這是我從一個簡短的脫脂得到: https://www.chef.io/blog/2013/02/05/chef-11-in-depth-attributes-changes/

+0

是的,這正是代碼所隱含的我的問題。爲了獲得更多樂趣,請參閱我編輯的帖子中的實際錯誤。 –

相關問題