2015-05-21 57 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

是的,这正是代码所隐含的我的问题。为了获得更多乐趣,请参阅我编辑的帖子中的实际错误。 –

相关问题