2015-05-21 3 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 
] 

Edit:

Так что спасибо за совершенно правильных рубин эск ответов, но на самом деле я попробовать массив хэши в нескольких вариантах, прежде чем перейти к 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, которую вы используете (и я, сегодня!), Несовместима с шеф-поваром 11+.Смотрите эту ссылку:

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

Теперь вы должны указать, какой уровень старшинства вы хотите записать при установке атрибутов; доступ к атрибутам на узле напрямую только для чтения.

линия, которая erroring здесь делает именно это:

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

Если вы хотите использовать это, таким образом, вы должны сделать принять одну из нескольких подходов:

  1. Вставьте кулинарную книгу в jruby и исправьте ее. Это невероятно старый, и ни одна из существующих прямых вилок не поддерживает шеф-повара 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

Try:

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

Обратите внимание, что внутренние структуры данных определяются с фигурными скобками, а не квадратные скобки.

  • [] «s создать массив
  • {}» s сделать Hash

вы создавали массив массивов, но то, что вы действительно хотите это массив хэшей.

EDIT

Документы, кажется, показывает, вы могли бы попробовать что-то вдоль линий:

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

Это то, что я получил от краткого обезжиренного из: https://www.chef.io/blog/2013/02/05/chef-11-in-depth-attributes-changes/

+0

Да, это точно так же, как код стоял, когда я окончательно набрал свой вопрос. Дополнительную забаву см. В фактической ошибке в моем отредактированном сообщении. –

Смежные вопросы