我有一个用于安装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-esque响应,但实际上我在转向SO之前尝试了几种变体中的哈希方法。疲劳让我误解了最初出现在我的问题中的结构。
我看到的问题似乎与Chef和您在上面看到的定义有关。我得到的错误如下......
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:
答案 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!
因此,如果你想使用它,你必须采取以下几种方法之一:
一个例子是:
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
考虑到适当的调整量,这实际上是有效的。使用此精确块的示例Chef客户端输出将是:
> Recipe: mycompany-jruby::default
> * gem_package[some-package] action install
> - install version #.#.# of package some-package
答案 1 :(得分: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/