Назад | Перейти на главную страницу

Слияние массивов атрибутов Chef

Допустим, у меня есть две кулинарные книги, Foo и Bar. В кулинарной книге Foo атрибуты / default.rb содержат следующее:

default[:test] = [{:baz => 'A', :qux => 'B'}]

В кулинарной книге B я хотел бы расширить этот массив другим объектом (т.е. объединить два массива): {:baz => 'C', :qux => 'D'}, в идеале - по рецепту.

Я попробовал поставить следующий рецепт бара, или файл атрибутов:

default[:test] = [{:baz => 'C', :qux => 'D'}]

Ожидается, что эти два будут объединены и в результате получится:

node[:test] == [{:baz => 'A', :qux => 'B'}, {:baz => 'C', :qux => 'D'}]

Но этого не происходит. Вместо этого во время запуска Chef-Solo в массиве содержится только один из двух объектов. Я также пробовал с default.override и default.set с такими же результатами. Как мне объединить два массива?

Спасибо.

Если вы хотите добавить отдельные хеш-элементы в массив, вы можете сделать это с помощью оператора вставки << вместо оператора присваивания =

В кулинарной книге А

# Create the default attribute as an array
default[:test]=[{:baz => 'A', :qux => 'B'}]

В кулинарной книге B

# Using array insertion on an existing array
default[:test] << {:baz => 'C', :qux => 'D'}



Если не гарантируется, что порядок списка выполнения будет A, B, тогда вам нужно принять меры против попыток вставить в массив, который еще не существует.

В кулинарной книге А

default[:test] ||= []
default[:test] << {:baz => 'A', :qux => 'B'}

В кулинарной книге B

default[:test] ||= []
default[:test] << {:baz => 'C', :qux => 'D'}



Если вы хотите объединить 2 массива, просто используйте + =

# In cookbook A
default[:test]=[{:baz => 'A', :qux => 'B'}]

# In cookbook B
default[:test] += [ {:baz => 'C', :qux => 'D'}, {:baz => 'E', :qux => 'F'} ]

Вы можете попробовать использовать метод Chef DeepMerge из второго рецепта, например:

a = Chef::Mixin::DeepMerge.merge(node[:test], [ (new array here) ])

a будет содержать слитые хэши!